'' * 'weeks' => '' * 'day' => '' * 'hour' => '' * 'minute' => '' * ) * @return string * 0 1 2 3 4 5 * * * * * * * * - - - - - - * | | | | | | * | | | | | +----- day of week (0 - 6) (Sunday=0) * | | | | +----- month (1 - 12) * | | | +------- day of month (1 - 31) * | | +--------- hour (0 - 23) * | +----------- min (0 - 59) * +------------- sec (0-59) */ public static function parseCron(array $param):string { $cron = ''; $where = isset($param['where']) ? $param['where'] : null; //条件 $weeks = isset($param['weeks']) ? $param['weeks'] : null; //星期 $day = isset($param['day']) ? $param['day'] : null; //天 $hour = isset($param['hour']) ? $param['hour'] : null; //时 $minute= isset($param['minute']) ? $param['minute'] : null; //分 $second= isset($param['second']) ? $param['second'] : '*'; //秒 if ($where === null || !in_array($where, self::WHERE)) { throw new \InvalidArgumentException('Invalid cron param where'); } //TODO:参数验证 switch ($where) { case 'day': //每天 $cron = sprintf(self::cron_minute, $minute, $hour, '*', '*', '*'); break; case 'day_n': //N天 $cron = sprintf(self::cron_minute, $minute, $hour, '*/'.$day, '*', '*'); break; case 'hour': //每小时 $cron = sprintf(self::cron_minute, $minute, '*', '*', '*', '*'); break; case 'hour_n': //N小时 $cron = sprintf(self::cron_minute, $minute, '*/'.$hour, '*', '*', '*'); break; case 'minute': //每分钟 $cron = sprintf(self::cron_minute, '*', '*', '*', '*', '*'); break; case 'minute_n': //N分钟 $cron = sprintf(self::cron_minute, '*/'.$minute, '*', '*', '*', '*'); break; case 'second': //每秒 $cron = sprintf(self::cron_second, '*', '*', '*', '*', '*', '*'); break; case 'second_n': //N秒 $cron = sprintf(self::cron_second, '*/'.$second, '*', '*', '*', '*', '*'); break; case 'week': //每周 $cron = sprintf(self::cron_minute, $minute, $hour, '*', '*', $weeks); break; case 'month': //每月 $cron = sprintf(self::cron_minute, $minute, $hour, '*', $day, '*'); break; } return $cron; } /** * 解析计划任务命令 * @param array $param * @return string */ public static function parseCommand(array $param):string { return Command::parse($param); } /** * 创建计划任务文件 * @param string $filename 文件的完整路径 * @param mixed $param 数据 * @return bool|int 结果 */ public static function writeCronFile($filename, $param) { return Conf::set($filename, $param, 'json', true); } /** * 获取文件路径 * @param string $filename 文件名 * @param string $dir 子目录 * @param string $suffix 扩展名 * @return string 文件的完整路径 */ public static function getFilePath($filename = '', $dir = 'cron_dir', $suffix = '.crontab') { clearstatcache(); $_dir = cron_path() . DIRECTORY_SEPARATOR . $dir; is_dir($_dir) or mkdir($_dir, 0777, true); return $_dir . DIRECTORY_SEPARATOR . $filename . $suffix; } /** * 根据任务名字,拼接lock文件路径 * @param string $filename * @return string */ public static function getLockFile($filename = '') { return self::getFilePath($filename, self::lock_dir, self::lock_suffix); } /** * 根据任务名字,拼接pid文件路径 * @param string $filename * @return string */ public static function getPidFile($filename = '') { return self::getFilePath($filename, self::pid_dir, self::pid_suffix); } /** * 拼接任务log文件的完整路径 * @param string $filename * @return string */ public static function getLogFile($filename = '') { return self::getFilePath($filename, self::log_dir, '.log'); } /** * 根据uuid运行任务 * @param string $uuid * @return bool */ public static function runCron(string $uuid = ''):bool { $cronFilename = Config::filename['crontab']; $cronAll = Conf::get($cronFilename, Constant::config_format, []); $cron = array_key_exists($uuid, $cronAll) ? $cronAll[$uuid] : []; if (isset($cron['switch']) && booleanParse($cron['switch'])) { self::execute($cron['command'], $cron['uuid']); return true; } return false; } /** * 读取计划任务的日志 * @param string $uuid * @return string */ public static function readLogs(string $uuid = ''):string { $logFile = self::getLogFile($uuid); $log = Conf::get($logFile, 'raw', '', true); return $log; } /** * 清空计划任务日志 * @param string $uuid * @return bool */ public static function clearLogs(string $uuid = ''):bool { $logFile = self::getLogFile($uuid); $ret = Conf::set($logFile, date('Y-m-d H:i:s').' 清理日志'.PHP_EOL, 'raw', true); return is_bool($ret) ? $ret : ($ret >= 10 ? true : false); } /** * 异步执行命令 * @descr 原理为php的程序执行函数后台执行 * @param string $cmd * @param string $logFile */ public static function execute($cmd = '', $logFile = '') { $logFile = self::getLogFile($logFile); if(DIRECTORY_SEPARATOR === '\\') { pclose(popen('start /B '.$cmd.' >> '.$logFile, 'r')); } else { pclose(popen($cmd.' >> '.$logFile.' 2>&1 &', 'r')); //exec($cmd.' >> '.$logFile.' 2>&1 &'); } } }