#!/usr/bin/env php getMessage()}" . PHP_EOL); } } // 2. 发现注解任务 (检查类上的 #[Crontab] 注解) foreach (get_declared_classes() as $className) { try { $reflect = new ReflectionClass($className); if ($reflect->isAbstract()) continue; if (!in_array(Kiri\Crontab\TaskInterface::class, class_implements($className), true)) continue; $attributes = $reflect->getAttributes(Kiri\Crontab\Annotate\Crontab::class); if (empty($attributes)) continue; $instance = $attributes[0]->newInstance(); $expr = $instance->buildExpression(); if ($expr === '') continue; Kiri\Crontab\TaskRegistry::register([ 'class' => $className, 'name' => $instance->name !== '' ? $instance->name : $className, 'expression' => $expr, 'status' => $instance->status, ]); } catch (\Throwable) {} } echo "[Crontab] 任务总数: " . TaskRegistry::count() . PHP_EOL; // PID 文件和日志文件 $pidFile = $config['scheduler']['pid_file'] ?? (getcwd() . '/storage/crontab.pid'); $logFile = $config['scheduler']['log_file'] ?? ''; // 创建命令实例 $command = new CrontabCommand($pidFile, $logFile); // 路由到对应操作 try { match ($action) { 'start' => $command->start($config), 'stop' => $command->stop(), 'restart' => $command->restart($config), 'status' => $command->status(), default => fwrite(STDERR, "未知操作: {$action} (支持: start|stop|restart|status)" . PHP_EOL), }; } catch (\Throwable $throwable) { fwrite(STDERR, "执行失败: {$throwable->getMessage()}" . PHP_EOL); fwrite(STDERR, "{$throwable->getTraceAsString()}" . PHP_EOL); exit(1); }