'./Log/ExpiredProductsCleaner', // 日志目录 'retain_days' => 60, // 日志保留天数(改为60天清理) 'file_prefix' => 'ExpiredProductsCleaner' // 日志文件前缀 ]; // 生成时间相关变量 $now = new DateTime(); $currentDate = $now->format('Y-m-d'); $logFile = sprintf("%s/%s_%s.log", $config['log_dir'], $config['file_prefix'], $currentDate); // 自动创建日志目录 if (!is_dir($config['log_dir']) && !mkdir($config['log_dir'], 0777, true)) { error_log("无法创建日志目录: {$config['log_dir']}"); return; } // 构建日志内容(含毫秒时间戳) $timestamp = $now->format('[Y-m-d H:i:s]') . sprintf('.%03d', (float)$now->format('u')/1000); $logLine = sprintf("%s <%s> - %s\n", $timestamp, strtoupper($type), $content); // 高性能写入(使用资源句柄+flock避免并发冲突) try { $handle = fopen($logFile, 'a'); // 追加模式打开 if (flock($handle, LOCK_EX)) { // 获取独占锁 fwrite($handle, $logLine); flock($handle, LOCK_UN); // 释放锁 } fclose($handle); } catch (Exception $e) { error_log("日志写入失败: " . $e->getMessage()); } // 控制台输出(可选调试) echo $logLine; // 智能清理(每天只执行一次清理检查) $cleanFlagFile = $config['log_dir'] . '/.last_clean'; if (!file_exists($cleanFlagFile) || (time() - filemtime($cleanFlagFile)) > 86400) { $expireDate = $now->modify("-{$config['retain_days']} days")->getTimestamp(); foreach (glob($config['log_dir'] . "/{$config['file_prefix']}_*.log") as $file) { if (filemtime($file) < $expireDate) { @unlink($file); } } touch($cleanFlagFile); // 更新清理标记时间 } } $语句 = "SELECT * FROM purchases WHERE expiry_time < NOW() -- 过期时间早于当前时间 AND status = 'expiring' ORDER BY expiry_time; "; 日志写入(">>>==================================>>>","执行中"); 日志写入("ExpiryReminder 任务开始","提示"); 日志写入("查询中","提示"); $结果 = @数据库运行($语句); if (!$结果) { 日志写入("无结果","提示"); die(); } 日志写入("查询结果","提示"); 日志写入(">>>==================================>>>","结果"); 日志写入(@转JSON($结果),"数据"); 日志写入(">>>==================================>>>","结果"); 日志写入("开始循环","提示"); foreach ($结果 as $业务元数据) { 日志写入(">>>==================================>>>","任务"); $用户ID = $业务元数据["user_id"]; $业务ID = $业务元数据["purchase_id"]; $业务状态 = $业务元数据["status"]; $业务名称 = $业务元数据["name"]; $到期时间 = $业务元数据["expiry_time"]; $产品标识 = $业务元数据["product_id"]; 日志写入("提取业务ID ".$业务ID,"提示"); 日志写入("提取用户ID ".$用户ID,"提示"); 日志写入("提取业务状态 ".$业务状态,"提示"); $dateString = $到期时间; // 创建目标日期对象并设置时间为0点 $targetDate = DateTime::createFromFormat('Y-m-d H:i:s', $dateString); $targetDate->setTime(0, 0, 0); // 创建当前日期对象并设置时间为0点 $today = new DateTime(); $today->setTime(0, 0, 0); // 计算日期差异 $interval = $today->diff($targetDate); // 获取天数差 $剩余天数 = $interval->days; // 处理过去或未来的情况 if ($interval->invert) { $剩余天数 = -$剩余天数; } $语句 = "SELECT * FROM users WHERE id = $用户ID;"; $用户数据 = @数据库运行($语句); $用户数据 = @reset($用户数据); $QQ = $用户数据["qq"]; 日志写入("获取邮件模板","提示"); $邮件模板 = @file_get_contents("./Res/ExpiredProductsCleaner.html"); $search = ["[到期时间]", "[业务名称]", "[业务ID]"]; $replace = [$到期时间, $业务名称, $业务ID]; $邮件模板 = str_replace($search, $replace, $邮件模板); 日志写入("正在发送邮件","提示"); $结果 = 发送邮件接口( $QQ.'@qq.com', '关于业务的重要通知', $邮件模板 ); if ($结果 === 200) { 日志写入("已发送","成功"); } else { 日志写入("发送失败 " . $结果,"错误"); } $语句 = "SELECT * FROM products WHERE product_id = '$产品标识';"; 日志写入("获取产品元数据中","提示"); $产品元数据 = @reset(@数据库运行($语句)); 日志写入("获取结果","提示"); 日志写入(">>>==================================>>>","结果"); 日志写入(@转JSON($产品元数据),"数据"); 日志写入(">>>==================================>>>","结果"); $产品模块 = $产品元数据["module"]; $产品周期 = $产品元数据["subscription_period"]; $模块路径 = "../ProductsModule/".$产品模块."/Main.php"; 日志写入("载入模块 ".$产品模块,"提示"); require_once $模块路径; 日志写入("删除业务中","提示"); $结果 = @转JSON(@删除业务($业务元数据,$产品元数据)); 日志写入("结果 ".$结果,"结果"); $语句 = "UPDATE purchases SET status = 'expired' WHERE purchase_id = '$业务ID'; "; @数据库运行($语句); 日志写入("已更新业务状态","提示"); } 日志写入("任务结束","提示"); 日志写入(">>>==================================>>>","结束"); ?>