你的 writeLog 函数已经按天拆分(lj_日期.log),这对于普通流量足够了。但如果某一天的日志量特别大(比如达到几百MB甚至GB),单个文件依然可能打开慢、下载困难、甚至导致内存溢出。 针对 PHP 5.6 环境,有以下几种按日期自动拆分的改进方案: 方案一:按小时拆分(推荐,简单有效) 将文件名精确到小时,每个小时一个文件,最大文件体积约为一天日志量的 1/24。 php function writeLog($data) { $logDir = __DIR__ . '/logs/'; if (!is_dir($logDir)) mkdir($logDir, 0755, true); // 改为小时粒度:lj_2025-06-02_14.log $logFile = $logDir . 'lj_' . date('Y-m-d_H') . '.log'; file_put_contents($logFile, '[' . date('Y-m-d H:i:s') . '] ' . $data . PHP_EOL, FILE_APPEND); } 优点:实现简单,单个文件最大约 1 小时的数据量,性能足够。 缺点:如果峰值小时也很大(如活动大促),仍可能爆文件。 方案二:按文件大小自动拆分(最精准) 当文件大小超过阈值(例如 50MB),自动创建新文件,加上序号(如 _1, _2)。 php function writeLog($data) { $logDir = __DIR__ . '/logs/'; if (!is_dir($logDir)) mkdir($logDir, 0755, true); // 基础文件名(按天) $baseName = $logDir . 'lj_' . date('Y-m-d'); $logFile = $baseName . '.log'; // 检查当前文件是否超过 50MB if (file_exists($logFile) && filesize($logFile) > 50 * 1024 * 1024) { // 寻找可用的序号文件 $index = 1; while (file_exists($baseName . '_' . $index . '.log')) { $index++; } $logFile = $baseName . '_' . $index . '.log'; } file_put_contents($logFile, '[' . date('Y-m-d H:i:s') . '] ' . $data . PHP_EOL, FILE_APPEND); } 优点:每个文件严格不超过阈值(例如 50MB),永远可读。 缺点:当天会生成多个文件,需要自行管理清理策略。 方案三:按小时 + 按大小双重保障 先按小时分文件,如果小时文件依然过大,再触发大小拆分(文件名加序号)。 php function writeLog($data) { $logDir = __DIR__ . '/logs/'; if (!is_dir($logDir)) mkdir($logDir, 0755, true); $baseName = $logDir . 'lj_' . date('Y-m-d_H'); $logFile = $baseName . '.log'; // 大小限制 50MB if (file_exists($logFile) && filesize($logFile) > 50 * 1024 * 1024) { $idx = 1; while (file_exists($baseName . '_' . $idx . '.log')) { $idx++; } $logFile = $baseName . '_' . $idx . '.log'; } file_put_contents($logFile, '[' . date('Y-m-d H:i:s') . '] ' . $data . PHP_EOL, FILE_APPEND); } 优点:既照顾了按时间查看的便利,又绝对保证文件大小可控。 缺点:文件名较长,但可接受。 🧹 配套建议:自动清理旧日志 无论采用哪种拆分方式,长期运行都会积累大量日志文件。建议在 writeLog 中触发一次清理(例如每 100 次写入清理一次,或单独写一个定时任务)。 php // 清理超过 30 天的日志 function cleanOldLogs($logDir, $days = 30) { $files = glob($logDir . 'lj_*.log'); $now = time(); foreach ($files as $file) { if (is_file($file) && $now - filemtime($file) > $days * 86400) { unlink($file); } } } 在 writeLog 开头调用(可以加随机概率,避免每次写入都扫描): php if (rand(1, 100) === 1) { // 1% 概率执行清理 cleanOldLogs($logDir, 30); } ⚠️ PHP 5.6 注意事项 filesize() 对于超过 2GB 的文件在 32 位系统上可能返回负数,但我们的拆分策略会阻止文件达到那么大的尺寸,所以安全。 如果使用方案二或三,在高并发下可能存在竞态条件(两个进程同时检查文件大小,然后都尝试创建新文件)。极端情况可加 flock 或使用独立的日志类。但对于普通 Web 请求量,上述代码足够稳定。