Планировщик задач PHP: полное руководство по cron-задачам и Task Scheduler

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Планировщик задач 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])) {                    

Рекомендаций