Перейти к содержимому
docs.
WORKSPACE

Документации проектов

Открыть каталог проектов
Localzet ServerАсинхронный PHP-серверTriangleФреймворк и компонентыMIX IDИдентификация и интеграцииHack APIПубличные API хакатонаACNПроект и компонентыUserlay / UserNetПроект и компонентыAxiomПроект и компонентыМесседжинг через почтуПроект и компонентыLWT / JWT / JOSEПроект и компонентыФинансовая аналитика KimaiПроект и компонентыМультипарадигмальная БДПроект и компонентыZorin PlatformПроект и компонентыZorin TrustПроект и компонентыFloraScope / VegwatchПроект и компонентыaegis-qДокументация проектаaevumdbДокументация проектаauditДокументация проектаauto-invest-managerАвтотрейдерcaine-companionДокументация проектаcertbot-cloudflareДокументация проектаClusterLocalzet Server / ClustercmdveilДокументация проектаConsolePHP CLICronБиблиотеки Localzet Server✓data-connectorДокументация проектаdevice-controlDevice Controlenn-projectДокументация проектаEventsБиблиотеки Localzet ServerflowsintДокументация проектаforgeДокументация проектаHttpClientБиблиотеки Localzet ServerinterpreterСобственный языкinvariaДокументация проектаkeynotesДокументация проектаknotrouteKnotroutelaravel-personal-analyticsДокументация проектаlocalzet-osДокументация проектаmeridianДокументация проектаMQTTБиблиотеки Localzet Servernano-kernelСобственная ОСNoterДокументация проектаpersonal-analyticsДокументация проектаProxyБиблиотеки Localzet ServerPSRБиблиотеки Localzet ServerPSR-7Библиотеки Localzet Serverrschs-monitorДокументация проектаsemsealДокументация проектаshardsealДокументация проектаSocketIOБиблиотеки Localzet ServerSOCKS5Библиотеки Localzet Serverstandalone-analyticsДокументация проектаstatic-php-cliДокументация проектаStorageБиблиотеки Localzet ServersutureДокументация проектаtempoweaveДокументация проектаttsСинтез речиTunnelБиблиотеки Localzet Serverui-kitUI KitvesperДокументация проектаWebAnalyzerWebAnalyzerzorin-access-brokerДокументация проектаzorin-authority-brokerДокументация проектаzorin-authority-sdk-phpДокументация проектаzorin-authority-sdk-pythonДокументация проектаzorin-authority-sdk-tsДокументация проектаzorin-client-intelДокументация проектаzorin-device-core-aospДокументация проектаzorin-host-agentДокументация проектаzorin-native-labДокументация проектаzorin-nodeДокументация проектаzorin-opsДокументация проектаdonstu-python-sdkДокументация проектаfloortraceFloortraceserver-rsLocalzet Server / Cluster
Каталог

Cron состоит из двух частей: CronParser проверяет выражение и вычисляет секунды запуска внутри выбранной минуты; Cron регистрирует callback и ставит одноразовые таймеры Localzet Server.

Это расписание внутри PHP-процесса. Оно не добавляет задания в системный crontab и не сохраняет их после завершения worker.

Манифест требует PHP ^8.1 и Localzet Server ^4.5:

Окно терминала
composer config repositories.localzet-cron vcs https://github.com/localzet/Cron
composer require localzet/cron:dev-main

Требование Server 4.x относится к планировщику Cron. Для самостоятельного разбора строки класс CronParser не вызывает Server или Timer. Не подменяйте требуемую версию Server 7.x только по совпадению имён классов.

Пять полей задают минуту, час, день месяца, месяц и день недели. В шестипольном выражении перед ними добавляются секунды.

ПолеДиапазон
Секунда0–59; при пяти полях используется 0
Минута0–59
Час0–23
День месяца1–31
Месяц1–12
День недели0–6, воскресенье — 0

В поле можно использовать число, *, список через запятую, диапазон через дефис и шаг через /.

*/15 * * * * * каждые 15 секунд выбранной минуты
0 9 * * 1-5 в 09:00 по будним дням
0,30 * * * * * на секундах 0 и 30
0 */2 * * * * на нулевой секунде каждой второй минуты

Названия месяцев/дней, @daily, L, W, # и номер воскресенья 7 не являются поддерживаемыми формами. День месяца и день недели проверяются одновременно: выражение с обоими ограничениями требует совпадения обоих полей. Это отличается от crontab-реализаций с правилом «день месяца ИЛИ день недели».

use localzet\CronParser;
date_default_timezone_set('UTC');
$parser = new CronParser();
$minute = strtotime('2026-10-17 12:00:00 UTC');
foreach ($parser->parse('0,30 * * * * *', $minute) as $timestamp) {
echo gmdate('H:i:s', $timestamp), PHP_EOL;
}

Результат:

12:00:00
12:00:30

parse() сначала проверяет минуту, час, календарную дату и день недели у $startTime. Если они совпали с правилом, возвращает $startTime + second для каждого значения поля секунд. Если нет — пустой массив.

Передавайте начало минуты. При 12:00:20 для секунд 0,30 получатся 12:00:20 и 12:00:50; парсер не обнуляет секунды самостоятельно. Если время приходит извне, нормализуйте его:

$minute = $timestamp - $timestamp % 60;
$times = $parser->parse($rule, $minute);

Парсер не перебирает будущие минуты. Пустой массив не означает, что расписание никогда не сработает: это отсутствие совпадений в рассматриваемой минуте. Часовой пояс берётся из date_default_timezone_set()/настроек PHP, отдельного параметра timezone нет.

if (!$parser->isValid($rule)) {
throw new InvalidArgumentException('Unsupported schedule');
}

isValid() проверяет форму строки и разбор сегментов, но не гарантирует наличие допустимых значений. Например, 99 * * * * проходит эту проверку и не даст ни одной подходящей минуты. Положительный шаг обязателен: */0 отклоняется.

Для пользовательского интерфейса ограничьте ввод перечисленными формами и диапазонами. Не используйте один isValid() как доказательство, что задача получит хотя бы одно время запуска. Не предоставляйте числовую форму 5/10 как «начиная с 5»: реализация шага начинает перебор с нижней границы поля; для заданного начала используйте явный диапазон 5-59/10.

Создавайте расписание после запуска event loop worker, например в его обработчике старта:

use localzet\Cron;
$job = new Cron('0 */5 * * * *', static function (): void {
refreshCounters();
}, 'refresh-counters');

refreshCounters() — прикладная функция. Сам Cron не создаёт очередь, отдельный процесс или транзакцию. Callback выполняется в event loop; блокирующий запрос или длительный расчёт задерживает остальные события этого процесса.

Первое зарегистрированное задание ставит почти немедленный timer сканирования. Дальше сканирование планируется к следующей границе минуты. Поскольку сканер вызывает парсер с текущим временем, а не нормализованным началом минуты, первоначальный запуск посреди минуты может сдвинуть времена на текущую секунду. Для задач с жёсткой точностью и пропуском прошедших срабатываний эту семантику нужно учитывать отдельно.

$id = $job->getId();
$removed = Cron::remove($id);
// Equivalent to $job->destroy().

Удаление исключает задание из следующего сканирования. Уже поставленные для него одноразовые Timer callback не отменяются: их ID в объекте задания не сохраняются. remove() не является гарантированной отменой ближайшего запуска.

Каждый worker имеет независимое статическое расписание. Если одинаковый код старта выполняется в четырёх процессах, будут четыре запуска. Для единственного исполнителя регистрируйте Cron только в назначенном процессе либо используйте прикладную блокировку с понятной политикой истечения.

Необработанная ошибка проверки правила возникает при работе сканера, а не обязательно в конструкторе Cron. Проверяйте правило до регистрации. Ошибки callback обрабатываются нижележащим Timer/event loop, собственного механизма повторов Cron не добавляет.

<?php
declare(strict_types=1);
use localzet\CronParser;
require __DIR__ . '/vendor/autoload.php';
date_default_timezone_set('UTC');
$parser = new CronParser();
$minute = strtotime('2026-10-17 12:00:00 UTC');
$times = $parser->parse('*/15 * * * * *', $minute);
echo json_encode(array_map(static fn (int $time): string => gmdate('H:i:s', $time), $times), JSON_THROW_ON_ERROR), PHP_EOL;

Методы, возвращаемые значения и ограничения

Исходный код · AGPL-3.0