Статьи

Планирование задач в WordPress: руководство разработчика плагинов

Планирование выполнения определенных функций за раз в будущем является ключевой особенностью API WordPress. Он был добавлен в API разработчиков в WordPressversion 2.0. Это также тема, которая плохо понимается многими разработчиками, поскольку она лишь кратко описана в документации WordPress. Помимо облегчения задач обслуживания, планирование кода, который будет выполняться в будущем, открывает множество интересных возможностей для разработчиков плагинов. Вот несколько реальных сценариев, в которых возможность планирования выполнения кода будет полезна для разработки плагинов:

  • Плагин веб-аналитики должен иметь возможность генерировать еженедельный отчет о статистике использования сайта, а затем отправлять электронное письмо администратору веб-сайта.
  • Плагину почтовой рассылки электронной почты может потребоваться доставлять электронную почту на серверы, где существуют почасовые ограничения. Плагину придется ставить в очередь исходящие электронные письма и отправлять заданное число каждый час.
  • Генератор изображений диаграммы может собирать данные из базы данных, генерировать изображение и сохранять его в кеше, а не генерировать его при каждом запросе — это позволит избежать ненужной нагрузки на базу данных.
  • Плагину резервного копирования потребуется активировать функцию один раз в неделю, чтобы он мог создать резервную копию базы данных и отправить электронное письмо администратору сайта.
  • Плагин для членства на веб-сайте потребует возможность прекращения подписки в конце месяца.
  • Плагин виджета боковой панели 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 и изменяет частоту резервного копирования на еженедельную, а не ежедневную. В этом случае плагин базы данных должен изменить частоту процедуры резервного копирования. Здесь мы сталкиваемся с некоторым препятствием: API планирования WordPress не позволяет нам изменять периодичность перехвата, который уже был запланирован. Нам нужно сначала удалить ежедневное расписание, а затем прикрепить новый еженедельный хук.

Теперь, когда вы знаете, как планировать и отменять планирование задач, у вас остается вопрос о местонахождении вашего кода для настройки этого расписания. Если ваш плагин должен начать выполнение задач сразу после активации плагина, задачи должны быть зарегистрированы в пределах активации. Хук активации предоставляется 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 экземпляров скрипта. Вскоре не осталось больше памяти для какого-либо другого процесса, и сценарий начал влиять на других владельцев веб-сайтов на сервере общего хостинга. Урок здесь заключается в том, что вы должны тщательно выбирать интервал повторения для ваших ресурсоемких процедур.
Используйте флаги при использовании общих ресурсов
Запланированные задачи часто используют файловую систему или определенные таблицы базы данных. Одновременный доступ или операции с этими ресурсами могут привести к повреждению или разрушению целостности данных. Это может произойти, когда ваш плагин имеет две или более задач, которые полагаются на один и тот же файл данных или таблицу базы данных. Обязательно используйте блокировку чтения / записи для доступа к вашим ресурсам.