Каждый разработчик рано или поздно сталкивается с необходимостью выполнять какие-то действия по расписанию: рассылки, очистка кэша, синхронизация данных. В Yii2 для этого есть удобные инструменты. Сегодня разберём, как подружить cron с Yii2 и написать свой планировщик задач.
Что такое cron и зачем он нужен в Yii2
Cron — это системный планировщик в Unix-подобных системах. Он запускает команды по расписанию. В Yii2 мы можем создавать консольные команды, которые cron будет вызывать. Это идеально для фоновых задач: отправка email, обновление статистики, резервное копирование.
Представьте, что вы хотите каждый день в 3 часа ночи чистить логи. Вместо того чтобы просыпаться и делать это вручную, вы пишете команду и говорите cron'у: «Запускай её каждую ночь». Yii2 даёт удобный интерфейс для таких команд.
Создаём консольную команду в Yii2
Для начала убедимся, что у нас есть консольное приложение. В стандартном шаблоне Yii2 advanced есть папка console. Если вы используете basic, создайте её. Внутри будет файл controllers для команд.
Создадим команду для очистки кэша. Например, CacheController с действием actionClear.
cache->flush()) {
echo "Кэш очищен!\n";
return 0;
}
echo "Не удалось очистить кэш.\n";
return 1;
}
}
Теперь эту команду можно запустить вручную: php yii cache/clear. Убедитесь, что путь к yii правильный — обычно он в корне проекта.
Настраиваем cron для запуска команды
Откройте crontab на сервере командой crontab -e. Добавьте строку, которая будет запускать нашу команду каждый день в 3:00.
0 3 * * * /usr/bin/php /path/to/project/yii cache/clear >> /var/log/yii-cache.log 2>&1
Здесь 0 3 * * * означает «в 3:00 каждый день». /usr/bin/php — путь к PHP (уточните через which php). /path/to/project/yii — путь к вашему Yii-скрипту. Логи перенаправляем в файл, чтобы потом можно было посмотреть, что происходило.
Чтобы проверить, что cron работает, можно временно поставить запуск каждую минуту: * * * * * и посмотреть логи.
Планировщик задач внутри Yii2
Иногда cron'а недостаточно: нужно гибко управлять расписанием из админки, без правки crontab. Тогда на помощь приходит планировщик задач. В Yii2 нет встроенного, но можно использовать расширения, например yii2-scheduler, или написать свой.
Рассмотрим простой вариант: таблица в БД с задачами и cron, который раз в минуту проверяет, что нужно выполнить.
Создадим миграцию для таблицы scheduler_task:
createTable('scheduler_task', [
'id' => $this->primaryKey(),
'command' => $this->string()->notNull(),
'cron_expression' => $this->string()->notNull(),
'last_run' => $this->integer(),
'next_run' => $this->integer(),
'status' => $this->smallInteger()->defaultValue(1),
]);
}
public function safeDown()
{
$this->dropTable('scheduler_task');
}
}
Теперь команда, которая будет запускаться каждую минуту и проверять задачи:
where(['<=', 'next_run', $now])
->andWhere(['status' => 1])
->all();
foreach ($tasks as $task) {
// Выполняем команду
$output = [];
$returnVar = 0;
exec(Yii::getAlias('@app/yii') . ' ' . $task->command, $output, $returnVar);
// Обновляем время следующего запуска
$task->last_run = $now;
$task->next_run = $this->calculateNextRun($task->cron_expression, $now);
$task->save();
}
}
private function calculateNextRun($cronExpression, $currentTime)
{
// Здесь можно использовать библиотеку для парсинга cron-выражений
// Например, dragonmantank/cron-expression
// Для простоты примера просто добавим 1 час
return $currentTime + 3600;
}
}
В crontab добавляем запуск каждую минуту:
* * * * * /usr/bin/php /path/to/project/yii scheduler/run
Теперь задачи можно добавлять через админку, и они будут выполняться по расписанию. Для парсинга cron-выражений советую подключить библиотеку dragonmantank/cron-expression.
Сравнение подходов: чистый cron vs планировщик в Yii2
Что выбрать? Зависит от задачи. Вот таблица для сравнения.
| Критерий | Чистый cron | Планировщик в Yii2 |
|---|---|---|
| Гибкость расписания | Меняется только в crontab | Можно менять из админки |
| Логирование | Только через перенаправление вывода | Можно писать в БД, файлы, отправлять уведомления |
| Сложность настройки | Низкая | Средняя (нужно писать код) |
| Зависимость от сервера | Высокая (нужен доступ к crontab) | Низкая (достаточно одного cron на запуск проверки) |
Если у вас простые задачи и нет необходимости менять расписание часто — чистый cron проще. Если же требуется управление из веб-интерфейса, логирование и гибкость — планировщик в Yii2 оправдан.
Полезные советы и подводные камни
- Пути к PHP и Yii: В crontab всегда указывайте полные пути. Переменные окружения могут отличаться от тех, что в терминале.
- Права на файлы: Убедитесь, что пользователь, от которого работает cron, имеет права на запись в логи и кэш.
- Обработка ошибок: В консольных командах используйте try-catch, чтобы неожиданное исключение не ломало весь процесс.
- Тестирование: Запускайте команды вручную перед добавлением в cron. Убедитесь, что они работают.
- Мониторинг: Настройте уведомления об ошибках. Например, отправляйте email при ненулевом коде возврата.
dragonmantank/cron-expression. Она умеет вычислять следующую дату запуска по cron-выражению.
Заключение
Мы разобрали, как работать с cron и планировщиком задач в Yii2. Начали с простых консольных команд, научились запускать их через cron, а затем создали гибкий планировщик с хранением задач в БД. Теперь вы можете автоматизировать рутину и спать спокойно.
Помните: автоматизация — это не роскошь, а необходимость для любого серьёзного проекта. Используйте cron и планировщики, чтобы сосредоточиться на более важных задачах.



