应使用 endroid/qr-code(v4+)替代过时的 phpqrcode,因其支持 PHP 8.1+、Composer 自动加载、多格式输出(PNG/SVG)、精细参数控制(纠错等级、尺寸、颜色、Logo)、可返回字符串或文件,并允许自主设置 Content-Type、缓存头等 HTTP 响应头,确保兼容性与安全性。

PHP 生成二维码,别用过时的 QRcode 类库(如原生 phpqrcode),它不维护、无命名空间、不兼容 PHP 8.1+,且默认输出到浏览器导致无法控制内容类型或缓存。
为什么 phpqrcode 在现代项目里大概率会报错
常见错误包括:Deprecated: preg_replace(): Passing null to parameter #3 ($subject)(PHP 8.1+)、headers already sent(因内部直接 echo 图像二进制)、Class 'QRcode' not found(未正确引入或无自动加载)。它把图像数据直接写入响应体,没留出设置 Content-Type 或 Cache-Control 的机会,也不支持返回 string 或 resource。
- PHP 8.0+ 下多数方法已废弃或行为变更,硬改源码风险高
- 不支持 Composer 自动加载,需手动
require多个文件 - 生成 PNG 时依赖 GD,但错误提示模糊,调试困难
- 无法指定纠错等级(L/M/Q/H)或像素大小以外的精细参数
推荐方案:用 endroid/qr-code(v4+)替代
这是目前最活跃、文档清晰、支持 PSR-17/18、可输出多种格式(PNG/SVG/BMP)、能返回二进制或 Data URI 的主流方案。安装后可完全控制输出方式和 HTTP 头。
- 安装命令:
composer require endroid/qr-code - 基础用法(返回 PNG 二进制):
$qrCode = new \Endroid\QrCode\QrCode('https://example.com'); $qrCode->setSize(300); $qrCode->setMargin(10); header('Content-Type: image/png'); echo $qrCode->writeString(); - 如需保存到文件:
$qrCode->writeFile('/path/to/qrcode.png') - 如需 SVG:
(new \Endroid\QrCode\QrCode('text'))->writeString('svg') - 纠错等级设为高可用:
$qrCode->setEncoding('UTF-8')->setErrorCorrectionLevel(\Endroid\QrCode\ErrorCorrectionLevel::HIGH)
动态生成时必须处理的三个头信息
绕开 phpqrcode 的“自动输出”陷阱,关键在于自己掌控响应头。哪怕只是 echo 二进制,也要提前声明:
立即学习“PHP免费学习笔记(深入)”;
-
Content-Type必须匹配实际输出格式(image/png/image/svg+xml) -
Content-Disposition: inline; filename="qrcode.png"可让浏览器正确识别为图像而非下载 -
Cache-Control: public, max-age=31536000对静态二维码非常必要——避免每次请求都重生成
漏掉任意一项,都可能导致图片显示为空白、被下载而非渲染、或被 CDN 缓存成乱码。
注意 SVG 输出在 IE 和部分旧安卓 WebView 中不兼容
虽然 endroid/qr-code 支持 SVG,但它本质是 XML 文本,某些老旧环境无法解析内联 <svg>。若目标用户包含企业内网(IE11)或低版本安卓 App 内嵌 WebView,优先用 PNG,并确保 GD 扩展已启用(php -m | grep gd 验证)。SVG 更适合后台导出或现代 Web 管理界面预览场景。
复杂点不在“怎么画”,而在“怎么安全地交到前端手里”——头信息、编码、缓存、兼容性,每一步漏判都可能让二维码扫不出。



















