Кеш и задачи по расписанию
Запрос к чужому сервису или тяжёлую выборку незачем выполнять при каждом открытии страницы. Результат сохраняют на время — в транзиент. А то, что должно происходить регулярно — очистка, синхронизация, рассылка, — поручают планировщику WP-Cron.
Транзиенты
Транзиент — значение с ограниченным сроком жизни:
function mytheme_get_rates(): array
{
$rates = get_transient('mytheme_rates');
if ($rates !== false) {
return $rates;
}
$response = wp_remote_get('https://api.example.com/rates', ['timeout' => 5]);
if (is_wp_error($response)) {
return [];
}
$rates = json_decode(wp_remote_retrieve_body($response), true) ?: [];
set_transient('mytheme_rates', $rates, HOUR_IN_SECONDS);
return $rates;
}get_transient() возвращает false, если значения нет или срок истёк. Тогда данные получают заново и сохраняют на час.
Константы времени
| Константа | Значение |
|---|---|
MINUTE_IN_SECONDS | 60 |
HOUR_IN_SECONDS | 3600 |
DAY_IN_SECONDS | 86400 |
WEEK_IN_SECONDS | 604800 |
Сброс кеша
Сохранённое значение удаляют, когда данные изменились:
add_action('save_post_book', function () {
delete_transient('mytheme_top_books');
});Объектный кеш
По умолчанию транзиенты лежат в таблице настроек. Если на сервере установлен Redis или Memcached и подключён плагин объектного кеша, они автоматически переезжают в память, а в коде можно пользоваться и группами:
$books = wp_cache_get('top', 'books');
if ($books === false) {
$books = get_posts(['post_type' => 'book', 'numberposts' => 5]);
wp_cache_set('top', $books, 'books', HOUR_IN_SECONDS);
}Без такого плагина wp_cache_set() хранит значение только до конца текущего запроса.
Задача по расписанию
// books.php
register_activation_hook(__FILE__, function () {
if (!wp_next_scheduled('books_daily_cleanup')) {
wp_schedule_event(time(), 'daily', 'books_daily_cleanup');
}
});
add_action('books_daily_cleanup', function () {
// удалить черновики старше месяца
});
register_deactivation_hook(__FILE__, function () {
wp_clear_scheduled_hook('books_daily_cleanup');
});wp_schedule_event() связывает расписание с именем хука, а работу выполняет обычный add_action(). Встроенные интервалы: hourly, twicedaily, daily, weekly.
Разовая задача
wp_schedule_single_event(time() + 10 * MINUTE_IN_SECONDS, 'books_send_reminder', [$orderId]);Как работает WP-Cron
WP-Cron — не настоящий планировщик. Он проверяет расписание, когда кто-то открывает сайт. На сайте без посетителей задача не выполнится вовремя, а на нагруженном проверка идёт при каждом запросе. Поэтому на рабочем сайте встроенный запуск отключают и вызывают его системным cron:
// wp-config.php
define('DISABLE_WP_CRON', true);*/5 * * * * cd /var/www/blog && wp cron event run --due-nowПроверка
wp cron event list
wp cron event run books_daily_cleanup
wp transient delete --allЧастая ошибка
Вызов wp_schedule_event() без проверки wp_next_scheduled() — да ещё и на хуке init — добавляет новую задачу при каждой загрузке страницы. Через день в расписании тысячи копий, и сайт выполняет их все. Планируйте задачу один раз, при активации плагина, и снимайте при деактивации.