Планировщик задач PHP: полное руководство
Планировщик задач (Task Scheduler) — это критически важный инструмент для любого веб-приложения, работающего на PHP. Он позволяет автоматизировать выполнение рутинных операций: отправку email-рассылок, очистку кэша, генерацию отчетов, синхронизацию данных с внешними API и многое другое. В отличие от ручного запуска скриптов, планировщик гарантирует своевременное и надежное выполнение задач без участия администратора.
Базовые подходы к реализации планировщика на PHP
Существует два основных способа реализации планировщика задач в PHP-проектах:
- Системный cron (Linux/Unix) — использование встроенного демона cron для вызова PHP-скриптов по расписанию.
- Пользовательский планировщик (Task Scheduler) — реализация логики планирования непосредственно в коде PHP с использованием циклов и проверок времени.
1. Системный cron с PHP
Самый распространенный и производительный подход. Вы создаете PHP-скрипт, который выполняет нужные действия, а затем добавляете запись в crontab сервера.
Пример PHP-скрипта для cron (cron_job.php):
<?php
// cron_job.php - выполняет очистку устаревших сессий
require_once 'config.php';
require_once 'db.php';
$stmt = $pdo->prepare("DELETE FROM sessions WHERE last_activity < NOW() - INTERVAL 1 DAY");
$stmt->execute();
// Логирование выполнения
file_put_contents('logs/cron.log', date('Y-m-d H:i:s') . " - Сессии очищены\n", FILE_APPEND);
?>
Запись в crontab (выполнять каждый час):
0 * * * * /usr/bin/php /var/www/html/cron_job.php
2. Пользовательский Task Scheduler на PHP
Если у вас нет доступа к системному cron (например, на shared-хостинге), можно реализовать планировщик непосредственно в PHP. Для этого используется специальный скрипт, который запускается при каждом посещении сайта или по HTTP-запросу.
Пример простого планировщика (task_scheduler.php):
<?php
class TaskScheduler {
private $tasks = [];
private $lastRunFile = 'last_run.json';
public function addTask($name, callable $callback, $interval) {
$this->tasks[] = [
'name' => $name,
'callback' => $callback,
'interval' => $interval // в секундах
];
}
public function run() {
$lastRun = $this->getLastRunTimes();
foreach ($this->tasks as $task) {
$lastTime = $lastRun[$task['name']] ?? 0;
if (time() - $lastTime >= $task['interval']) {
echo "Выполняю задачу: {$task['name']}\n";
call_user_func($task['callback']);
$lastRun[$task['name']] = time();
}
}
file_put_contents($this->lastRunFile, json_encode($lastRun));
}
private function getLastRunTimes() {
if (file_exists($this->lastRunFile)) {
return json_decode(file_get_contents($this->lastRunFile), true);
}
return [];
}
}
// Использование
$scheduler = new TaskScheduler();
$scheduler->addTask('send_newsletter', function() {
// Логика отправки рассылки
echo "Рассылка отправлена\n";
}, 3600); // Каждый час
$scheduler->addTask('clean_cache', function() {
// Очистка кэша
array_map('unlink', glob('cache/*.cache'));
echo "Кэш очищен\n";
}, 86400); // Раз в сутки
$scheduler->run();
?>
3. Продвинутый планировщик с поддержкой CRON-выражений
Для более гибкого управления расписанием можно реализовать поддержку классических cron-выражений (минута, час, день, месяц, день недели).
Пример парсера cron-выражений:
<?php
class CronParser {
public static function match($cronExpression, $timestamp = null) {
$timestamp = $timestamp ?? time();
$parts = preg_split('/\s+/', $cronExpression);
$minute = date('i', $timestamp);
$hour = date('G', $timestamp);
$day = date('j', $timestamp);
$month = date('n', $timestamp);
$weekday = date('w', $timestamp);
$checks = [$minute, $hour, $day, $month, $weekday];
foreach ($parts as $i => $part) {
if ($part !== '*' && !self::checkPart($part, $checks[$i])) {