CMS 系統常需「一鍵清除快取」功能,解決資料更新不即時問題。ThinkPHP 預設快取儲存在 /Runtime/Temp/ 及 /Runtime/~runtime.php。
<?php
public function cache() {
// AJAX POST 請求處理
if ($_POST['type']) {
$type = $_POST['type'];
$name = explode('-', $type); // 以 "-" 分割多個目錄
$count = count($name);
// 專案根目錄下的 Runtime 路徑
$abs_dir = dirname(dirname(dirname(dirname(__FILE__))));
$pa = $abs_dir . 'indexRuntime';
$runtime = $abs_dir . 'indexRuntime~runtime.php';
// 刪除核心快取檔
if (file_exists($runtime)) {
unlink($runtime);
}
// 逐一刪除指定子目錄
for ($i = 0; $i < $count; $i++) {
$this->rmFile($pa, $name[$i]);
}
$this->ajaxReturn(1, '清除成功', 1);
} else {
$this->display();
}
}
// 遞迴刪除目錄下所有檔案
public function rmFile($path, $fileName) {
$path = preg_replace('/(\/){2,}|(\\){1,}/', '/', $path); // 修正路徑分隔符
$path .= $fileName;
if (is_dir($path)) {
if ($dh = opendir($path)) {
while (($file = readdir($dh)) !== false) {
// 跳過 . 與 ..
if ($file != '.' && $file != '..') {
$full = $path . '/' . $file;
if (is_dir($full)) {
$this->rmFile($path, $file); // 遞迴刪除子目錄
} else {
unlink($full);
}
}
}
closedir($dh);
// 可選:刪除空目錄 @rmdir($path);
}
}
}
?>
<script src="__PUBLIC__/admin/js/jquery.js"></script>
<script type="text/javascript">
$(function() {
$('#button').click(function() {
if (confirm("確認要清除快取?")) {
var $type = $('#type').val();
$.post('__URL__/clear', {type: $type}, function(data) {
alert("快取清理成功");
});
}
return false;
});
});
</script>
<!-- 表單範例 -->
<input type="hidden" id="type" value="Temp-Cache-Logs" />
<button id="button">一鍵清除快取</button>
| 問題 | 改進方案 |
|---|---|
| 硬編碼路徑層級 | 使用 RUNTIME_PATH 常數或 C('RUNTIME_PATH') 取得標準路徑 |
| 遞迴刪除未處理子目錄 | 在 rmFile 中判斷 is_dir 並遞迴呼叫 |
| 無權限檢查 | 加入後台權限驗證(RBAC/ACL) |
| 大量檔案超時 | 分批次 AJAX 請求、或使用 CLI 指令 php think clear |
| 快取類型不完整 | 支援 Cache::clear()、S('key', null)、Opcode 快取清理 |
// TP5+ 內建指令
php think clear
// 程式碼中清除
use think\facade\Cache;
Cache::clear(); // 清除所有快取
Cache::rm('key'); // 刪除指定鍵
Cache::tag('tagName')->clear(); // 按標籤清除