核心函數 cacheArr()
<?php
function cacheArr(array &$data): bool {
if (empty($data)) throw new Exception('陣列不可為空');
// 取得變數名稱 (僅限全域變數)
$varName = null;
foreach ($GLOBALS as $name => $value) {
if ($value === $data) { $varName = $name; break; }
}
if (!$varName) throw new Exception('無法取得變數名稱,請確保傳入全域變數');
// 開啟輸出緩衝
ob_start();
echo "<?php\n";
echo "\${$varName} = ";
var_export($data, true); // 產生合法 PHP 代碼
echo ";\n?>";
$content = ob_get_clean();
$file = __DIR__ . "/cache/{$varName}.arr.php";
// 確保目錄存在
if (!is_dir(dirname($file))) mkdir(dirname($file), 0755, true);
return file_put_contents($file, $content) !== false;
}
// 使用範例
$config = ['app_id' => 123, 'secret' => 'abc', 'domains' => ['a.com', 'b.com']];
cacheArr($config); // 產生 cache/config.arr.php
// 載入快取
require __DIR__ . '/cache/config.arr.php';
print_r($config); // 還原陣列
?>
原理說明
- 透過
$GLOBALS 反查變數名稱 (僅適用於全域變數)。
- 使用
var_export() 產生可直接 require 的 PHP 代碼 (比 serialize() 更快、可讀、支援 Opcode 快取)。
- 輸出緩衝捕獲內容寫入
.arr.php 檔案。
優缺點比較
| 方案 | 讀取速度 | 寫入速度 | 可讀性 | Opcode 快取 |
| var_export .php | 極快 (Opcode) | 慢 | 高 | 支援 |
| serialize() 檔案 | 快 | 快 | 低 | 不支援 |
| json_encode() | 中 | 中 | 高 | 不支援 |
| Redis/Memcached | 極快 (記憶體) | 極快 | 低 | 不適用 |
適用場景
- 極少變動的設定資料 (語系包、國家代碼、選單結構)。
- 單機部署、無 Redis 環境的專案。
- 需利用 PHP Opcode 快取 (OPcache) 加速讀取的場景。
注意事項
- 變數名稱反查不可靠 (多個變數指向同一陣列、非全域變數),建議改為**傳入檔案名稱參數**。
- 大型陣列 (超過 1MB) 寫入較慢,建議改用
igbinary_serialize() + 檔案或 Redis。
- 快取失效策略:檔案修改時間、版本號、手動清除。