最稳妥的修改方式是加载→修改→重新生成代码。用include加载配置数组,修改后以var_export生成合法PHP代码,补上前缀写入并备份原文件;避免正则替换,复杂逻辑应改用json等格式。

为什么不用 serialize() 而选 var_export()
var_export() 生成的是合法 PHP 代码,可直接 include 或 eval 加载,比 serialize() 更适合“写入文件 + 后续复用”的场景。它保留了数组结构、类型(如 false、null、整数),且输出可读——调试时打开缓存文件一眼能看清数据。但注意:它不处理闭包、资源、对象(除非实现 __set_state()),纯关联数组或数值数组最稳妥。
如何安全写入并加载缓存文件
关键在路径、权限、原子性、类型还原。别直接 file_put_contents($file, var_export($data, true)) 就完事。
- 加
PHP_EOL结尾,避免和后续?>拼接出语法错误 - 用临时文件 +
rename()保证写入原子性,防止读到半截内容 - 开头加
<?php return,结尾加;,让文件变成“可返回值的 PHP 脚本” - 加载时统一用
require(不是include),失败就报错,不静默忽略
示例写入:
$cacheFile = '/tmp/user_list.cache.php'; $tempFile = $cacheFile . '.tmp'; $content = '<?php return ' . var_export($rows, true) . ';' . PHP_EOL; file_put_contents($tempFile, $content) && rename($tempFile, $cacheFile);
示例加载:
立即学习“PHP免费学习笔记(深入)”;
$data = require $cacheFile; // $data 就是原数组,类型完整,无需 <code>unserialize()</code> 或 <code>json_decode()</code>
缓存失效与时间戳校验怎么做
本地文件缓存没自动过期机制,得自己加时间戳判断。不要把时间戳塞进缓存文件里再解析——那又绕回去了。更简单:用独立的 .meta 文件,或直接读缓存文件的 filemtime()。
- 查库前先
if (file_exists($cacheFile) && time() - filemtime($cacheFile) ,5 分钟内有效 - 若需精确控制(比如某条记录更新后立即失效),改用带哈希前缀的文件名:
$key = md5("users:active:{$tenant_id}"); $file = "/tmp/{$key}.cache.php" - 写缓存前确保目录存在且可写:
is_writable(dirname($cacheFile)) || mkdir(dirname($cacheFile), 0755, true)
哪些数据不能直接 var_export() 缓存
遇到这些情况会报错或丢失信息,必须预处理:
- 数据库连接资源(
PDO、mysqli对象)——早该在查询后fetch_all()或fetchAll()转成数组 - 含循环引用的对象 —— 不适用此方案,换
json_encode()+ 类型重建 - 浮点数精度问题:
var_export(0.1 + 0.2)输出0.30000000000000004,如需精确,转字符串或用number_format()格式化后再存 - 包含匿名函数或
__sleep()未定义的类实例 —— 直接跳过,或提前array_map('get_object_vars', $objects)剥离
实际项目中,缓存前加一层 is_array($data) && !empty($data) 检查,比硬扛异常更省心。文件缓存看着简单,但路径权限、时区差异、NFS 挂载延迟这些细节,往往在上线后才暴露。



















