PHP缓存控制:编辑发票后二维码图片无法强制刷新的问题求助
解决发票二维码缓存不更新问题
核心问题分析
你设置的PHP响应头和HTML meta标签仅对PHP生成的页面生效,而二维码PNG属于静态文件,服务器(Apache/Nginx)默认会给静态资源配置缓存策略,这才是浏览器缓存旧二维码的关键。即便给URL添加时间戳,若服务器仍返回静态文件的缓存头,浏览器仍可能优先使用缓存内容。
具体解决方案
1. 修改服务器静态文件缓存配置
针对存放二维码的qr目录,强制禁用缓存:
Nginx配置
在站点配置中添加以下规则,修改后重启Nginx生效:
location /qr/ { expires off; add_header Cache-Control "no-cache, no-store, must-revalidate"; add_header Pragma "no-cache"; add_header Expires "Fri, 30 Oct 1998 14:19:41 GMT"; }
Apache配置
在项目根目录的.htaccess文件中添加(若无.htaccess需先创建,确保Apache开启mod_headers模块):
<Directory "/path/to/your/project/qr"> Header set Cache-Control "no-cache, no-store, must-revalidate" Header set Pragma "no-cache" Header set Expires "Fri, 30 Oct 1998 14:19:41 GMT" </Directory>
2. 优化URL参数方案(服务器配置修改受限可选)
使用唯一性更强的参数替代时间戳,比如结合发票ID和修改时间生成哈希值:
$invoice_id = "1-20220004"; // 优先从数据库获取发票实际修改时间,而非当前时间 $last_modified = time(); $unique_param = md5($invoice_id . $last_modified); echo '<img src="qr/'.$invoice_id.'.png?q='.$unique_param.'" />';
确保发票修改后$last_modified同步更新,保证参数完全唯一。
3. 彻底规避缓存:动态生成文件名
最可靠的方式是每次修改发票后生成全新文件名的二维码,例如包含修改时间戳:
$invoice_id = "1-20220004"; $version = time(); $qr_file = "qr/{$invoice_id}-v{$version}.png"; // 清理该发票的旧二维码文件(可选,避免文件堆积) $old_files = glob("qr/{$invoice_id}-v*.png"); foreach ($old_files as $old_file) { unlink($old_file); } // 生成新二维码(替换为你的生成逻辑) generate_qr_code($qr_file, $new_invoice_data); // HTML中引用新文件 echo '<img src="'.$qr_file.'" />';
这种方式URL完全不同,浏览器绝对不会缓存旧文件。可配合定时任务(如Linux的crontab)定期清理3天前的旧二维码文件。
4. 验证生成逻辑正确性
确认删除旧文件和生成新文件的逻辑无权限或执行问题:
$qr_file = "qr/1-20220004.png"; if (file_exists($qr_file)) { if (!unlink($qr_file)) { error_log("无法删除旧二维码文件:{$qr_file},请检查目录权限"); } } // 生成新二维码后验证文件状态 if (file_exists($qr_file)) { echo "二维码文件修改时间:" . date("Y-m-d H:i:s", filemtime($qr_file)); } else { error_log("新二维码文件生成失败:{$qr_file}"); }
内容的提问来源于stack exchange,提问作者himi
相关产品推荐
相关产品推荐

