Учимся использовать WP-Cron в своих целях
WP-Cron – одна из наименее используемых особенностей WordPress – часто упускается из виду разработчиками. Однако ее применение – дело нешуточное. Начиная с кэширования и заканчивая уведомлениями об апдейтах, планирование cron-задач может использоваться с целью реализации неоспоримых преимуществ даже для самых простых WordPress-блогов. Присоединяйтесь к нам – в данной статье мы исследуем важные варианты применения данной системы.
Типичная cron-задача? Какая она?
Увидев слово «cron», вы, вероятно, поняли, с чем мы будем работать: планирование идеально рассчитанных по времени событий, которые будут запускаться в определенные временные отрезки. С другой стороны, WP-Cron – это не совсем то же самое, что и Unix cron-планировщик. Ключевое отличие состоит в том, как они выполняются; в отличие от фонового процесса, WP-Cron запускается всякий раз, когда посетитель открывает ваш WordPress-сайт. По существу, WP-Cron поддерживает очень важное качество неточной привязки ко времени.
Да, вы прочли верно: неточная привязка ко времени. Хотя слова «cron» и «точность» являются практически синонимами, они не гармонируют в системе WordPress. Но является ли это проблемой? Если рассматривать данный факт с позиции пользователя, то это автоматически становится плюсом.
Давайте приведем пример обычной cron-задачи, запускаемой каждые пять минут для обновления некоторой информации в базе данных, используемой на сайте. Если за 40 минут посетителей на сайте не было, то зачем выполнять это действие 8 раз? Все промежуточные значения будут либо устаревшими, либо неиспользуемыми. С другой стороны, если действие будет выполнено для первого пользовательского визита через (как минимум) 5 минут, то в таком случае мы выполним ту же задачу и предотвратим ненужные обновления. Иными словами, поскольку WP-Cron зависит от пользователей, у него есть преимущество: он запускается только тогда, когда присутствуют посетители.
Не ходите вокруг да около! Покажите мне!
Чтобы применить WP-Cron, давайте рассмотрим следующий часто используемый сервис управления RSS – FeedBurner. Безусловно, одна из наиболее популярных особенностей данного приложения – возможность подсчета количества RSS-подписчиков. После индексации счетчик подписчиков сайта может быть получен с помощью простого API вызова. Таким образом, получается, что данный вызов API может быть совершен один раз за просмотр страницы, чтобы передать число подписчиков посетителям. Однако это ведет к одной проблеме.
Открываем мир кэширования
Если API FeedBurner доступен один раз за просмотр страницы, это неизбежно приводит к совершению дополнительного HTTP-запроса – не говоря уже о запросе с других доменов – для каждого посетителя. В итоге растет время загрузки страниц.
Чтобы справиться с этой проблемой, важно сделать одну ключевую предпосылку, связанную с данным методом доставки: счетчик подписчиков RSS вряд ли будет обновлен во время каждого отдельного просмотра страницы. В действительности, FeedBurner обновляет свой счетчик лишь раз в день. Даже если его необходимо вывести молниеносно, так ли важен этот показатель для каждого посетителя? Играет ли роль тот факт, что счетчик несколько устарел, но при этом обновится в течение дня?
В наших целях бесполезно получать счетчик RSS подписчиков при каждом просмотре страницы. Вместо этого лучше получать его для первого посетителя, после чего уже использовать данное значение для всех последующих. После того, как пройдет день, можно будет обновить показатель счетчика. Такой процесс носит название кэширования. После обновления счетчик RSS-подписчиков кэшируется – сохраняется для последующего использования вместо постоянного пересчета – пока не пройдут сутки. Принимая во внимание данную информацию, мы можем перейти в мир WP-Cron.
Шаг 1. Исследуем документацию.
Чтобы понять WP-Cron, важно знать, где хранится вся необходимая документация. WordPress.org обеспечивает справку по каждой функции cron. Чтобы выполнить поставленную нами задачу, нам понадобится функция wp_schedule_event, которая требует четыре параметра:
- Time: временная метка UNIX, определяющая, когда событие должно быть инициировано
- Recurrence: как часто событие будет повторно инициировано после запланированного времени.
- Hook: хук, используемый для добавления функциональности, когда событие инициировано.
- Args: массив аргументов, который будет передаваться всем подцепленным функциям (необязательный параметр).
Наше событие будет инициировано, когда текущее время сравняется или превысит время, переданное в эту функцию, как отведенное на будущего посетителя сайта. Затем оно будет повторно инициировано на базе параметра повторения recurrence, который может быть задан как hourly (каждый час), twicedaily (два раза в день), daily (ежедневно) или none (никогда). Также можно задать и произвольное повторение события.
Для работы с событием используется хук. Хук WordPress можно считать заполнителем для действия. Действия могут быть присвоены хукам через WordPress-функцию add_action. Чтобы добавить обработчик функции к существующему хуку, можно вызвать:
add_action( 'hook_name', 'function_name' );
Где hook_name и function_name – это название хука и функции-обработчика соответственно.
Шаг 2. Вызываем функцию.
Поскольку FeedBurner обновляется один раз в день, мы определим ежедневное расписание, как в коде ниже:
wp_schedule_event( time(), 'daily', 'feedburner_refresh' );
Обратите внимание на то, что time() является текущей временной меткой UNIX, выражаемой в секундах. При запуске хук «FeedBurner Update» инициируется сразу же, и затем один раз в каждый день. Обратите внимание на то, что если мы просто поместим функцию в файл functions.php, то новое событие будет запланировано при каждой загрузке отдельных страниц. Это нам не требуется; мы хотим запланировать данное событие один раз. Самый простой способ сделать это – просто проверить, является ли событие уже запланированным. Это можно сделать с помощью функции wp_next_scheduled , которая вернет false, если событие не установлено на выполнение в будущем или время его следующего запуска отличается:
if( !wp_next_scheduled( 'feedburner_refresh' ) ) { wp_schedule_event( time(), 'daily', 'feedburner_refresh' ); }
Если нам нужно будет когда-нибудь отменить планирование данного события, это очень просто сделать с помощью функции wp_unschedule_event, которая принимает те же самые параметры, что и wp_schedule_event. Отметьте, что передаваемое время должно быть временем следующего события, которое может быть получено через wp_next_scheduled:
if( false !== ( $time = wp_next_scheduled( 'feedburner_refresh' ) ) ) { wp_unschedule_event( $time, 'feedburner_refresh' ); }
Мы можем также отменить планирование данного события через название хука, используя функцию wp_clear_scheduled_hook. Учтите, что такая альтернатива удалит также все остальные события, которые используют тот же самый хук.
wp_clear_scheduled_hook( 'feedburner_refresh' );
Теперь, когда наше событие запланировано, нам нужно добавить обработчик к нему:
add_action( 'feedburner_refresh', 'update_rss_subscriber_count' );
Здесь мы задаем функцию под названием update_rss_subscriber_count, которая будет вызываться тогда, когда инициирован хук feedburner_refresh. Пришло время написать эту функцию.
Шаг 4. Получаем счетчик подписчиков FeedBurner.
Чтобы получить счетчик подписчиков Feedburner в функции update_rss_subscriber_count, мы можем вызвать API FeedBurner через URL <https://feedburner.google.com/api/awareness/1.0/GetFeedData?uri=[NAME]>, где [NAME] – название нашего фида.
Это вернет XML-данные в следующей форме:
<rsp stat="ok"> <!-- This information is part of the FeedBurner Awareness API. If you want to hide this information, you may do so via your FeedBurner Account. --> <feed id="8olmjno1k05rb1som1frr6u854" uri="nettuts"> <entry date="2011-06-22" circulation="84673" hits="152325" reach="25865"/> </feed> </rsp>
Информация, которую мы ищем, находится в атрибуте circulation. Следующее регулярное выражение позволит легко получить эти данные:
circulation="(.*?)"
Наше регулярное выражение соответствует следующей фразе:
circulation= за словом circulation следует знак равенства;
“(.*?)” – кавычки и все что угодно внутри;
Передача выражения в функцию preg_match вернет массив соответствий, который будет содержать количество подписчиков в первой индексной позиции. Объединив эту информацию воедино, мы придем к следующему коду:
// find the FeedBurner url and get the data from it // change [NAME] to the name of your FeedBurner feed $url = 'https://feedburner.google.com/api/awareness/1.0/GetFeedData?uri=[NAME]'; $data = @file_get_contents( $url ); // @ will surpress errors // use a regular expression to parse the data $regex = '%circulation="(.*?)"%'; preg_match( $regex, $data, $matches ); // get the resultant count if available $count = false; if( $matches && $matches[1] ) $count = (int) $matches[1];
Шаг 5. Сохраняем количество подписчиков
Теперь, когда мы получили счетчик подписчиков, нам нужно сохранить его в доступном виде; вместо повторного перебора API XML-данных, посетители просто получат доступ к этому хранящемуся значению.
Вместо создания базы данных или файла для хранения информации, мы можем использовать еще одну особенность WordPress: опции. Опции WordPress – это простой способ хранения информации наряду с идентификацией имен. Опции удаления, добавления и доступа представляют собой простые функции:
- update_option( $name, $value ) – добавляет или обновляет опцию с именем $name и значением $value.
- delete_option( $name ) – удаляет опцию с именем $name.
- get_option( $name ) – Получает значение опции, связанной с именем $name.
Несмотря на то, что наш счетчик подписчиков не является в техническом плане параметром конфигурации, использование опций является одним из наиболее удобных способов – если не самым удобным – для того, чтобы хранить такие простые данные. Следовательно, чтобы сохранить наш счетчик, мы должны использовать метод update_option, который не только переопределит предыдущие значения, но и создаст опцию:
// if a count could not be found, do not update // instead, stick with the previous count if( $count !== false ) update_option( 'subscriber_count', $count );
Наша функция готова! После установки события, получения данных через FeedBurner API и сохранения требуемого значения нам осталось лишь вывести его. Полный код для функции планирования и извлечения – которую вы можете поместить в functions.php – может быть найден ниже:
// schedule the feedburner_refresh event only once if( !wp_next_scheduled( 'feedburner_refresh' ) ) { wp_schedule_event( time(), 'daily', 'feedburner_refresh' ); } add_action( 'feedburner_refresh', 'update_rss_subscriber_count' ); function update_rss_subscriber_count() { // find the FeedBurner url and get the data from it // change [NAME] to the name of your FeedBurner feed $url = 'https://feedburner.google.com/api/awareness/1.0/GetFeedData?uri=[NAME]'; $data = @file_get_contents( $url ); // @ will surpress errors // use a regular expression to parse the data $regex = '%circulation="(.*?)"%'; preg_match( $regex, $data, $matches ); // get the resultant count if available $count = false; if( $matches && $matches[1] ) $count = (int) $matches[1]; // if a count could not be found, do not update // instead, stick with the previous count if( $count !== false ) update_option( 'subscriber_count', $count ); }
Шаг 6. Вывод.
Счетчик подписчиков теперь можно вывести с помощью простого вызова функции в любом шаблоне:
echo get_option( 'subscriber_count' );
Заключение
Наш счетчик подписчиков RSS теперь оптимизирован; вместо того чтобы выводиться для каждого запроса, он кэшируется с помощью WP-Cron, сохраняя время ваших пользователей и снижая использование пропускной способности. Поскольку счетчик активируется только в том случае, когда на сайт фактически заходят посетители, наша функция является очень ленивой – термин, который в данном контексте можно считать положительным. Но, увы, в данной статье мы раскрыли лишь одно приложение WP-Cron. Остальное уже за вами.
Источник: wp.tutsplus.com