pbootcms定期自动清理缓存runtime
pbootcms更改index.php,新增:
// 引入runtime周清理工具 require dirname(__FILE__) . '/core/runtime_weekly_cleaner.php'; // 引用内核启动文件 require dirname(__FILE__) . '/core/start.php';
以下代码首次访问会执行一次,然后定期会清理并做日志记录,日志在/core/data/clean_log目录,runtime_weekly_cleaner.php文件内容:
<?php
/**
* Runtime目录定期清理工具(修复版)
* 修复重点:标记文件过期机制、权限检查、日志增强
*/
if (!defined('IS_INDEX')) {
exit('Access Denied!');
}
class RuntimeCleaner {
private $config;
public function __construct() {
$this->config = [
'runtime_path' => realpath(dirname(__DIR__) . '/runtime/') . '/',
'log_path' => realpath(__DIR__ . '/data/clean_log/') . '/',
'flag_file' => __DIR__ . '/data/clean_log/.cleaned'
];
}
public function execute() {
$this->ensureDirectories();
$flagFile = $this->config['flag_file'];
// 检查标记文件是否存在且未过期(3天)
if (file_exists($flagFile) && (time() - filemtime($flagFile)) < 3 * 86400) {
return;
}
$logContent = $this->generateLogHeader();
try {
$logContent .= $this->performCleanup();
touch($flagFile); // 更新标记文件时间戳
$logContent .= "标记文件已更新: " . date('Y-m-d H:i:s') . "\n";
} catch (Exception $e) {
$logContent .= "清理失败: " . $e->getMessage() . "\n";
$this->writeLog($logContent);
throw $e; // 重新抛出异常以便外部捕获
}
$this->writeLog($logContent);
}
private function ensureDirectories() {
// 创建日志目录(如果不存在)
if (!file_exists($this->config['log_path'])) {
if (!mkdir($this->config['log_path'], 0755, true)) {
throw new Exception("无法创建日志目录: " . $this->config['log_path']);
}
chmod($this->config['log_path'], 0755);
}
// 验证runtime目录
if (!is_dir($this->config['runtime_path'])) {
throw new Exception("Runtime目录不存在: " . $this->config['runtime_path']);
}
// 验证目录可写性
if (!is_writable($this->config['runtime_path'])) {
throw new Exception("Runtime目录不可写: " . $this->config['runtime_path']);
}
}
private function generateLogHeader() {
return sprintf(
"[%s] 开始清理任务\n运行时目录: %s\n磁盘剩余空间: %s\n",
date('Y-m-d H:i:s'),
$this->config['runtime_path'],
$this->formatBytes(disk_free_space($this->config['runtime_path']))
);
}
private function performCleanup() {
$stats = ['folders' => 0, 'files' => 0, 'size' => 0];
$logContent = "";
$items = new DirectoryIterator($this->config['runtime_path']);
foreach ($items as $item) {
if ($item->isDot()) continue;
$path = $item->getPathname();
try {
if ($item->isDir()) {
$this->deleteDirectory($path, $stats);
$stats['folders']++;
$logContent .= "已删除文件夹: " . $item->getFilename() . "\n";
} elseif ($item->isFile()) {
$stats['files']++;
$stats['size'] += $item->getSize();
if (!unlink($path)) {
throw new Exception("无法删除文件: " . $path);
}
}
} catch (Exception $e) {
$logContent .= "操作失败: " . $e->getMessage() . "\n";
}
}
return $logContent . sprintf(
"清理完成\n删除文件夹: %d 个\n删除文件: %d 个\n释放空间: %s\n剩余空间: %s\n",
$stats['folders'],
$stats['files'],
$this->formatBytes($stats['size']),
$this->formatBytes(disk_free_space($this->config['runtime_path']))
);
}
private function deleteDirectory($path, &$stats) {
$iterator = new RecursiveDirectoryIterator(
$path,
FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS
);
$files = new RecursiveIteratorIterator(
$iterator,
RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($files as $file) {
try {
if ($file->isFile()) {
$stats['files']++;
$stats['size'] += $file->getSize();
if (!unlink($file->getRealPath())) {
throw new Exception("无法删除文件: " . $file->getPathname());
}
} elseif ($file->isDir()) {
if (!rmdir($file->getRealPath())) {
throw new Exception("无法删除目录: " . $file->getPathname());
}
}
} catch (Exception $e) {
throw new Exception("删除操作失败: " . $e->getMessage());
}
}
if (!rmdir($path)) {
throw new Exception("无法删除主目录: " . $path);
}
}
private function writeLog($content) {
$logFile = $this->config['log_path'] . 'clean_log_' . date('Y-m') . '.log';
if (file_put_contents($logFile, $content, FILE_APPEND | LOCK_EX) === false) {
throw new Exception("无法写入日志文件: " . $logFile);
}
}
private function formatBytes($bytes) {
if ($bytes <= 0) return '0 B';
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$pow = floor(log($bytes, 1024));
$pow = min($pow, count($units) - 1);
return round($bytes / (1024 ** $pow), 2) . ' ' . $units[$pow];
}
}
// 执行清理(建议通过cron调用)
try {
(new RuntimeCleaner())->execute();
} catch (Exception $e) {
error_log("Runtime清理错误: " . $e->getMessage());
}
