- Плагин веб-аналитики должен иметь возможность генерировать еженедельный отчет о статистике использования сайта, а затем отправлять электронное письмо администратору веб-сайта.
- Плагину почтовой рассылки электронной почты может потребоваться доставлять электронную почту на серверы, где существуют почасовые ограничения. Плагину придется ставить в очередь исходящие электронные письма и отправлять заданное число каждый час.
- Генератор изображений диаграммы может собирать данные из базы данных, генерировать изображение и сохранять его в кеше, а не генерировать его при каждом запросе — это позволит избежать ненужной нагрузки на базу данных.
- Плагину резервного копирования потребуется активировать функцию один раз в неделю, чтобы он мог создать резервную копию базы данных и отправить электронное письмо администратору сайта.
- Плагин для членства на веб-сайте потребует возможность прекращения подписки в конце месяца.
- Плагин виджета боковой панели Twitter, который отправляет запрос в службу Twitter только один раз в час, чтобы получить и загрузить ваши последние твиты.
В этой статье я покажу вам, как работать с API WordPress для планирования задач, выполняемых в определенное время или через определенные промежутки времени. Предполагается, что вы уже знакомы с основами создания плагинов WordPress, в противном случае прочитайте страницу « Создание плагинов» в Кодексе WordPress , чтобы найти несколько стартовых указателей.
Прежде чем мы рассмотрим, как настроить запланированные задачи в вашем WordPress-плагине, вы должны понять, как WordPress выполняет запланированные задачи за кулисами. Каждый раз, когда кто-то посещает страницу сайта, WordPress проверяет, требуется ли какая-либо из запланированных функций. Быть выполненным. Это основано на интервале с момента последнего выполнения или времени, когда было запланировано задание. fsockopen
использует fsockopen
PHP fsockopen
чтобы сделать запрос к файлу wp-cron.php
который находится в установочном каталоге WordPress. Чтобы убедиться, что посетитель веб-сайта не затронут этим вызовом, время ожидания запроса очень мало (0,1 секунды). Инициировав запрос, WordPress не ждет ответа и продолжает предоставлять страницу пользователю. Тайм-аут в 0,1 секунды достаточен для wp-cron.php
файла wp-cron.php
cron.php. Первый оператор, который выполняет wp-cron.php
:
ignore_user_abort (истина);
Это гарантирует, что выполнение продолжается, даже если клиент, который запросил страницу, закрывает соединение (в противном случае это приведет к прекращению выполнения). Этот скрипт проверяет любые задачи, которые должны быть выполнены, основываясь на текущем времени и времени, когда они были выполнены в последний раз. Например, предположим, у вас есть задача, которая запланирована на почасовую работу и была в последний раз запущена в 16:13. Когда пользователь запрашивает страницу с вашего сайта в wp-cron.php
, wp-cron.php
пропустит вашу задачу, так как последний раз был безрезультатным, чем час назад. Через несколько минут, в 5:15 вечера, когда другой пользователь просматривает страницу, wp-cron.php
запустит вашу задачу.
Чтобы запланировать запуск функции как одноразового задания или повторяющейся задачи, вы просто присоединяете ее к хуку действий. Это позволяет нескольким функциям быть назначенными одному и тому же запланированному хуку. Если вы не знакомы с хуками действий WordPress, давайте сделаем краткий обзор, прежде чем посмотреть, как они применяются к планированию действий. Если вы уже знакомы с хуками действий WordPress, не стесняйтесь пропустить этот раздел и сразу перейти к разделу «Планирование». Задачи » .
Хук действия — это именованная группа функций, которые должны быть выполнены в выбранной точке. Любая функция, прикрепленная к данному хуку действий, будет выполнена после выполнения этого действия. Ядро WordPress определяет множество действий, которые, в свою очередь, запускаются во многих местах кода WordPresscore. Давайте рассмотрим пример: ядро WordPress включает в wp_head
функцию wp_head
, с которой вы, вероятно, wp_head
. Внутри этой функции вы найдете следующую строку кода:
do_action ( 'wp_head');
Функция wp_head
вызывается в разделе <head>
файла header.php
в теме WordPress. Когда вызывается эта функция, приведенная выше строка кода запускает выполнение любых функций, которые были связаны с wp_head
действия wp_head
. Важно различать метод wp_head
и wp_head
действия wp_head
: они имеют одинаковые имена, но aredistinct. Если мы хотим добавить таблицу стилей на все страницы без редактирования файла header.php
, мы просто создаем функцию ourown, которая генерирует нужный <link/>
, а затем присоедините эту функцию к действию wp_head
. Код ниже делает это:
// Эта функция генерирует функцию тега ссылки myplugin_generatestylesheet () {// Формируем URL-адрес файла css, хранящегося в каталоге плагинов $ pluginURL = get_bloginfo ('home'). '/ Wp-content / plugins / myplugin / mycss.css' ; // Записать его в браузер echo '<link href = "'. $ PluginURL. '" Type = "text / css" rel = "stylesheet" />';} // Теперь мы добавим эту функцию в действие wp_head. add_action ( 'wp_head', 'myplugin_generatestylesheet');
Ключом здесь является функция add_action
: она присоединяет нашу функцию myplugin_generatestylesheet
к wp_head
действий wp_head
. Теперь, когда метод wp_head
вызывает do_action('wp-head')
, будет вызвана наша функция и будет выведен тег link. Вы можете определить свои собственные действия и добавить в эту операцию столько функций, сколько захотите. Как мы вскоре увидим, это ключ к функциональности планирования WordPress.
В WordPress мы можем запланировать вызов функций двумя способами:
- Разовая задача — задача, которая должна быть выполнена один раз в указанное время
- Повторяющаяся задача — задача, которая выполняется с регулярными интервалами
Я пойду по каждому из них по очереди.
Чтобы запланировать действия, которые выполняются один раз в определенное время и никогда снова, мы используем функцию wp_schedule_single_event
мы определяем функцию, которую мы хотим запланировать:
function my_function () {// Сделайте что-нибудь. Что-нибудь.}
Далее мы добавляем эту функцию в наш хук действий. Подождите, нам нужно сначала создать хук действия, верно? Неправильно. Оказывается, нет. При добавлении функции к действию с новым именем создается новое действие. Итак, на этом шаге мы создаем как действие my_action
, так и добавляем функцию my_function
этому действию:
add_action ( 'my_action', 'My_function');
Наконец, мы планируем запуск ловушки действий в нужное время:
wp_schedule_single_event ($ метка времени, 'my_action');
В приведенной выше строке кода $timestamp
— это время, в которое мы хотим выполнить действие, отформатированное как метка времени Unix.
Функции, которые должны вызываться через регулярные промежутки времени, планируются с wp_schedule_event
функции wp_schedule_event
. Шаги, включенные в определение повторяющейся задачи, в остальном очень похожи на шаги для одноразовой задачи. Опять же, мы начнем с определения функции, содержащей код, который мы хотим периодически выполнять:
function my_periodic_function () {// Делайте что-нибудь регулярно.}
Добавляем функцию в новый хук действия:
add_action ( 'my_periodic_action', 'my_periodic_function');
Наконец, мы планируем выполнение действия с желаемой частотой:
wp_schedule_event ($ timestamp, 'hourly', 'my_periodic_action');
Эта функция принимает новый параметр: частоту ( 'hourly'
в приведенном выше примере). $timestamp
— это время, когда хук действия должен сначала выполняться, после чего он будет запускаться с частотой, определяемой вторым параметром. Последний параметр, как и в случае с wp_schedule_single_event
, представляет собой хук действия toschedule.WordPress определяет три частоты повторения: ежечасно, ежедневно и дважды в день. Однако, если вам нужна другая частота, никогда не бойтесь! Вы можете определить свои собственные частоты повторения.
Что если вам нужен период повторения, который короче, например, каждые пять минут или дольше, например раз в месяц? В этих случаях мы можем определить собственную частоту повторения и экспортировать ее в WordPress. Это делается путем присоединения функции к фильтру cron_schedules
:
add_filter ( 'cron_schedules', 'my_cron_definer'); function my_cron_definer ($ schedules) {$ schedules ['month'] = массив ('interval' => 2592000, 'display' => __ ('один раз в 30 дней')); вернуть $ расписаний;}
После этого мы можем использовать новую частоту при вызове wp_schedule_event
:
wp_schedule_event (время (), 'в месяц', 'my_action');
Это будет вызывать my_action
раз в 30 дней, начиная с текущего времени.
Допустим, администратор обнаружил, что их почтовый ящик продолжает заполняться резервными электронными письмами при использовании нашего плагина резервного копирования базы данных. Возможно, ежедневное резервное копирование излишне, учитывая скромный уровень активности в их блоге. Поэтому администратор входит в панель управления WordPress и изменяет частоту резервного копирования на еженедельную, а не ежедневную. В этом случае плагин базы данных должен изменить частоту процедуры резервного копирования. Здесь мы сталкиваемся с некоторым препятствием: API планирования WordPress не позволяет нам изменять периодичность перехвата, который уже был запланирован. Нам нужно сначала удалить ежедневное расписание, а затем прикрепить новый еженедельный хук.
Чтобы удалить все будущие экземпляры повторяющегося действия, следует использовать функцию wp_clear_scheduled_hook
. Синтаксис не может быть проще:
wp_clear_scheduled_hook ( 'name_of_hook');
Одноразовые события не wp_unschedule_event
с помощью функции wp_unschedule_event
. Использование этой функции не так просто, как планирование повторных событий. Синтаксис следующий:
wp_unschedule_event ($ timestamp, $ hook, $ arguments);
Здесь аргумент $timestamp
— это время, когда запланировано событие. Поскольку вы можете не знать, когда запланировано выполнение действия, вы можете использовать функцию wp_next_scheduled
чтобы извлечь время, а затем передать его в wp_unschedule_event
:
$ whenNext = wp_next_scheduled ('my_action'); wp_unschedule_event ($ whenNext, 'my_action');
Теперь, когда вы знаете, как планировать и отменять планирование задач, у вас остается вопрос о местонахождении вашего кода для настройки этого расписания. Если ваш плагин должен начать выполнение задач сразу после активации плагина, задачи должны быть зарегистрированы в пределах активации. Хук активации предоставляется WordPress и запускается при первом включении плагина. Когда ваш плагин деактивирован, все задачи, запланированные вашими плагинами, должны быть незапланированными. Это гарантирует, что WordPress не планирует повторяющиеся задачи, если ваш плагин будет активирован повторно. Это также гарантирует, что любой другой плагин, который использует задачи, запланированные вашими плагинами, не вызывает нежелательного поведения. Этот очень простой плагин демонстрирует как планирование задач, когда плагин активирован, так и их удаление, когда плагин деактивирован:
<? php / * Имя плагина: URI плагина моего плагина: http://www.sitepoint.com/ Описание: Плагин для изучения crontasks. * / register_activation_hook (__ FILE __, 'myplugin_activation'); / * Хук деактивации выполняется, когда плагин деактивирован * / register_deactivation_hook (__ FILE __, 'myplugin_deactivation'); / * Эта функция выполняется, когда пользователь активирует плагин * / function myplugin_ () {wp_schedule_event (time (), 'hourly', 'my_hook');} / * Эта функция выполняется, когда пользователь отключает плагин * / function myplugin_deactivation () {wp_clear_scheduled_hook ('my_hook');} / * Добавляем наша собственная функция для my_hook action.add_action ('my_hook', 'my_function'); / * Это функция, которая выполняется ежечасным повторяющимся действием my_hook * / function my_function () {// что-то сделать.}? >
При разработке плагинов, использующих запланированные задачи, часто бывает полезно увидеть, действительно ли задача была запланирована, и назначена ли ей правильная частота. Это можно сделать с помощью плагина ControlCore. Плагин Control Core был создан, чтобы помочь разработчикам плагинов в их работе, обеспечивая контроль над некоторыми аспектами ядра WordPress. Контроллер Core добавляет в панель администрирования раздел, в котором отображаются все задачи, запланированные на данный момент.
Этот метод планирования задач поставляется с несколькими предупреждающими метками:
- Знайте, что это не на 100% точно
- Для тех из вас, кто привык к системным задачам cron, очевидным недостатком API планирования WordPress является невозможность обеспечить выполнение запланированного действия в точное время. Хотя запланированные функции, безусловно, будут выполнены, они могут быть запущены немного позже, чем вы хотели бы. Это связано с тем, что WordPress полагается на трафик веб-сайта для выполнения триггерных задач. В тех случаях, когда на веб-сайте может отсутствовать достаточный трафик, запланированная задача может не выполняться в нужное время. В то время как действие было запланировано на 12:00, на самом деле оно может быть запущено в 12:45, потому что никто не заходил на сайт поздно ночью.
- Используйте соответствующие частоты
- Некоторое время назад я создал плагин, который генерировал некоторые страницы контента для блога, запрашивая веб-службу поиска Yahoo и веб-службу Twitter. Сценарий должен был запускаться каждые пять минут. Я написал плагин и настроил его для работы в myblog. На следующий день моя учетная запись веб-хостинга была временно приостановлена за использование чрезмерных ресурсов. Оказалось, что сценарии иногда выполнялись дольше пяти минут. Это означало, что новая задача часто начиналась раньше, чем завершалась предыдущая; после пары часов было запущено 12 экземпляров скрипта. Вскоре не осталось больше памяти для какого-либо другого процесса, и сценарий начал влиять на других владельцев веб-сайтов на сервере общего хостинга. Урок здесь заключается в том, что вы должны тщательно выбирать интервал повторения для ваших ресурсоемких процедур.
- Используйте флаги при использовании общих ресурсов
- Запланированные задачи часто используют файловую систему или определенные таблицы базы данных. Одновременный доступ или операции с этими ресурсами могут привести к повреждению или разрушению целостности данных. Это может произойти, когда ваш плагин имеет две или более задач, которые полагаются на один и тот же файл данных или таблицу базы данных. Обязательно используйте блокировку чтения / записи для доступа к вашим ресурсам.
Хотя возможно создание плагинов WordPress, которые выполняют периодические задачи без API планирования WordPress, делать это таким образом невыгодно. Процедура настройки вашего плагина станет более сложной, поскольку пользователям придется настраивать cron вручную. Сложные процедуры только уменьшают количество блоггеров, которые могут извлечь выгоду из использования вашего плагина. Процесс установки плагина должен быть простым, как нажатие в разделе плагинов панели администрирования WordPress. Используя встроенную в WordPress функциональность планирования, вы можете предоставить своим плагинам сложные функции, не делая их более сложными в использовании.