Каждый веб-разработчик рано или поздно сталкивается с необходимостью выполнять какие-то действия на сервере по расписанию: отправка рассылок, очистка кэша, обновление данных из внешних API. Вручную это делать неудобно, да и не нужно. На помощь приходит cron — планировщик задач в Unix-подобных системах. А если вы пишете на Yii (неважно, Yii2 или Yii3), то у вас есть встроенные инструменты для работы с фоновыми задачами. В этой статье я расскажу, как подружить cron с Yii, какие есть подводные камни и как сделать всё по-человечески.

Digital-студия WNDER

Что такое cron и зачем он нужен в Yii

Cron — это демон в Unix-системах, который запускает команды по расписанию. Вы задаёте время и команду, а он выполняет. В Yii для таких задач есть консольные команды (контроллеры). Они позволяют запускать код из вашего приложения через командную строку, используя все преимущества фреймворка: автозагрузку, конфигурацию, компоненты.

Зачем это нужно? Представьте, что у вас интернет-магазин. Нужно каждую ночь обновлять остатки товаров, отправлять письма брошенным корзинам, чистить старые логи. Писать отдельные скрипты — плохо, потому что они не будут знать о настройках вашего приложения. А консольные команды Yii — это те же контроллеры, только для терминала. Они используют ту же конфигурацию, те же модели, те же компоненты. Удобно!

Создаём консольную команду в Yii

В Yii2 консольные команды лежат в папке commands (или console/controllers в продвинутом шаблоне). Давайте создадим простую команду, которая будет чистить кэш.

cache->flush();
        echo "Кэш очищен!\n";
        return 0; // код возврата 0 означает успех
    }
}
?>

Теперь эту команду можно запустить из терминала: php yii cache/flush. Обратите внимание: команда возвращает 0 при успехе и ненулевой код при ошибке. Это важно для cron, чтобы понимать, успешно ли выполнилась задача.

Настраиваем cron для запуска команды

Чтобы cron знал о нашей команде, нужно добавить запись в crontab. Откройте crontab командой crontab -e и добавьте строку. Например, чтобы очищать кэш каждый день в 3 часа ночи:

0 3 * * * cd /path/to/your/project && php yii cache/flush >> /var/log/yii-cache.log 2>&1

Разберём по частям:

  • 0 3 * * * — минуты, часы, день месяца, месяц, день недели. Здесь: 0 минут, 3 часа, каждый день, каждый месяц, любой день недели.
  • cd /path/to/your/project — переходим в папку проекта, чтобы Yii нашёл конфигурацию.
  • php yii cache/flush — запускаем нашу команду.
  • >> /var/log/yii-cache.log 2>&1 — перенаправляем весь вывод (и stdout, и stderr) в лог-файл. Это очень полезно для отладки.

Не забывайте, что cron использует ограниченное окружение. Путь к PHP может быть не таким, как в вашем терминале. Чтобы узнать точный путь, выполните which php и используйте его в crontab.

Правило: Всегда указывайте полный путь к PHP и к папке проекта в crontab. Иначе cron может не найти исполняемый файл или конфигурацию Yii.

Планировщик задач в Yii2: модуль yii2-scheduler

Если вам нужно запускать задачи не по жёсткому расписанию cron, а с более гибкими условиями (например, каждые 5 минут, но только по будням), можно использовать расширения. Одно из популярных — yii2-scheduler. Оно позволяет описывать расписание прямо в коде на PHP, а не в crontab.

Установка через composer:

composer require --prefer-dist omnilight/yii2-scheduler

Затем настраиваем компонент в конфигурации:

'components' => [
    'scheduler' => [
        'class' => 'omnilight\scheduler\Scheduler',
        'tasks' => [
            [
                'class' => 'app\tasks\CacheFlushTask',
                'schedule' => '* * * * *', // каждую минуту
            ],
        ],
    ],
],

И создаём сам класс задачи:

cache->flush();
        return true; // или false при ошибке
    }
}
?>

После этого достаточно добавить в crontab одну строку, которая будет запускать планировщик каждую минуту:

* * * * * cd /path/to/project && php yii scheduler/run

Этот подход удобен тем, что всё расписание хранится в коде, а не в системном crontab. Легче версионировать и переносить между серверами.

Сравнение подходов: чистый cron vs планировщик Yii

Что выбрать? Зависит от задачи. Давайте сравним в таблице.

Критерий Чистый cron Планировщик Yii (yii2-scheduler)
Гибкость расписания Ограничена форматом cron Можно задавать любые условия на PHP
Управление из кода Нет, только через crontab Да, всё в конфигурации
Логирование Нужно настраивать вручную Встроенное, можно писать в БД
Простота настройки Минимальная Требует установки расширения

Для простых задач типа «раз в день» хватит и чистого cron. Для сложных сценариев с зависимостями и гибким расписанием лучше подойдёт планировщик.

Лайфхак: Если вы используете чистый cron, добавляйте в команду проверку блокировки, чтобы задача не запустилась повторно, если предыдущий запуск ещё не завершился. Например, через файл-блокировку или через компонент yii\mutex.

Обработка ошибок и логирование

Когда задача выполняется по расписанию, вы не видите, что пошло не так. Поэтому обязательно логируйте всё. В Yii можно настроить логирование для консольных приложений. В конфигурации console/config/main.php добавьте компонент log:

'components' => [
    'log' => [
        'targets' => [
            [
                'class' => 'yii\log\FileTarget',
                'levels' => ['error', 'warning', 'info'],
                'logFile' => '@runtime/logs/console.log',
            ],
        ],
    ],
],

Теперь все ошибки и предупреждения будут падать в файл. А ещё можно отправлять уведомления на email при критических ошибках. Для этого используйте yii\log\EmailTarget.

Внутри команды используйте Yii::error(), Yii::warning(), Yii::info() для записи в лог. И не забывайте возвращать правильный код завершения: 0 — успех, 1 — ошибка. Cron по коду может уведомить администратора, если настроить.

Заключение

Работа с кроном и планировщиком задач в Yii — это не rocket science, но есть нюансы. Главное: используйте консольные команды Yii, указывайте полные пути в crontab, логируйте всё и не забывайте про блокировки. Если задач много и они сложные — присмотритесь к расширениям вроде yii2-scheduler. Они упростят жизнь и сделают код чище.

Надеюсь, статья была полезной. Автоматизируйте рутину и дайте себе больше времени на интересные задачи!

Студия WNDER