php代码示例怎么实现数据缓存_php数据缓存代码示例【示例】

使用 apcu_store() 缓存数组时需确保数据可序列化,避免含资源句柄或闭包;键名须规范化,过期时间0表示进程级永不过期而非持久存储。

php代码示例怎么实现数据缓存_php数据缓存代码示例【示例】

PHP 用 apcu_store() 缓存数组数据时要注意什么

APCu 是 PHP 最轻量、最常用的用户级内存缓存扩展,但直接缓存含资源句柄(如 mysqli 对象、文件指针)或闭包的数组会静默失败,且不报错。缓存前必须确保数据可序列化。

  • apcu_store() 只接受标量、数组、对象(需实现 __serialize() 或能被 serialize() 处理)
  • 缓存键名不能含空格或控制字符,建议用 md5($key)str_replace([' ', '/'], '_', $key) 规范化
  • 过期时间设为 0 表示永不过期,但 APCu 进程重启后即丢失——别把它当持久存储
  • 示例:
    $data = ['user_id' => 123, 'name' => 'Alice'];
    apcu_store('user_123', $data, 300); // 5 分钟后自动失效

Redis 缓存 JSON 数据时为什么 json_encode() 后还要加 JSON_UNESCAPED_UNICODE

中文字段在 Redis 中显示为 /u4f60/u597d 不是 bug,是默认 JSON 编码行为;但后续用 JavaScript 或其他语言读取时,若没正确解码 Unicode 转义,会导致乱码或解析失败。

  • PHP 写入:用 json_encode($data, JSON_UNESCAPED_UNICODE) 确保中文原样存储
  • PHP 读取:json_decode($redis->get('key'), true) 即可还原数组,无需额外处理
  • Redis 命令行查值时看到中文,说明编码正确;看到 /u... 则说明写入时没加标志位
  • 性能影响极小,但能避免跨语言协作时的隐性问题

文件缓存用 file_put_contents() 配合 flock() 的必要性

高并发下多个请求同时写同一个缓存文件,不加锁会导致内容截断、覆盖或 JSON 格式损坏——这不是概率问题,是必然发生的竞态。

Mulan AI

Mulan AI

画布式AI视频创作平台,轻松制作爆款视频

下载

  • 必须用 fopen() + flock() + file_put_contents() 组合,不能只靠 file_put_contents($file, $content, LOCK_EX)(该 flag 仅对当前调用有效,不保证跨进程互斥)
  • 推荐写法:
    $fp = fopen($cacheFile, 'c');
    if (flock($fp, LOCK_EX)) {
        file_put_contents($cacheFile, json_encode($data), LOCK_EX);
        flock($fp, LOCK_UN);
    }
    fclose($fp);
  • 注意 'c' 模式打开文件,避免清空后再写入的窗口期
  • 缓存文件路径建议用 sys_get_temp_dir() . '/cache/',别放在 Web 可访问目录下

Memcached 存布尔值 true 为什么取出来变成 0

Memcached 协议本身不支持布尔类型,true 会被强制转成整数 1,而 false 转成空字符串 '';但 PHP 的 Memcached::get() 在遇到空字符串时会返回 false,导致真假混淆。

立即学习PHP免费学习笔记(深入)”;

  • 永远不要直接缓存 true / false,改用字符串 'true' / 'false' 或整数 1 / 0
  • 更稳妥的做法是缓存数组:['value' => $data, 'type' => 'bool'],读取后按 type 解析
  • 如果用的是 memcache(非 memcached)扩展,行为更不可靠,建议统一升级到 memcached
  • 这个坑在调试时很难复现,往往上线后流量一上来才暴露

缓存逻辑越简单越可靠,但“简单”不等于省略锁、忽略序列化边界、或假设扩展能自动处理类型。真正难的不是写缓存代码,而是预判它在哪种并发、哪种数据结构、哪种部署环境下会悄悄失效。

https://www.php.cn/faq/2030132.html

发表回复

Your email address will not be published. Required fields are marked *