phpqrcode生成二维码失败主因是GD扩展未启用或输出缓冲干扰;中文乱码需确保UTF-8编码并设容错级别M以上;保存文件需检查路径权限与绝对路径,输出浏览器须手动加header;自定义样式应生成后用GD/Imagick叠加处理。

phpqrcode 生成二维码失败:常见报错和基础依赖
直接跑不起来,大概率是缺 GD 扩展或输出被缓冲干扰。QRcode::png() 内部依赖 imagepng(),没开 GD 就会报 Call to undefined function imagepng()。Windows 下 PHP 默认不启用 GD,Linux 容易漏装 php-gd 包。
另外注意:函数默认直接输出二进制图片流,如果前面已有 echo、var_dump 或开启了 output_buffering,就会触发 Cannot modify header information 错误。
- 用
php -m | grep gd或extension_loaded('gd')确认 GD 已启用 - 调试时先加
ob_end_clean()清掉输出缓冲,再调QRcode::png() - 避免在生成前有任何 HTML 输出、空格、BOM 字符
中文内容乱码:字符编码与容错级别设置
传入中文字符串不加处理,生成的二维码扫出来是乱码或根本无法识别——不是库的问题,是编码没对齐。phpqrcode 原生只接受 UTF-8 字节流,但很多 PHP 文件本身是 GBK 编码保存的,file_get_contents() 或直接写死字符串时容易带入非 UTF-8 字节。
容错级别($errorCorrectionLevel)也影响中文稳定性:L(7%)、M(15%)、Q(25%)、H(30%)。中文信息量大,建议至少用 M,否则轻微污损就扫不出。
立即学习“PHP免费学习笔记(深入)”;
- 确保输入字符串是 UTF-8:
mb_convert_encoding($str, 'UTF-8', 'auto') - 别用
iconv('GBK', 'UTF-8', $str)硬转,可能崩掉非法字符;优先用mb_convert_encoding - 生成时显式指定容错:
QRcode::png($data, false, QR_ECLEVEL_M, 4)
保存文件 vs 直接输出:路径权限和 header 干扰
想把二维码存成文件却提示 failed to open stream: Permission denied,通常是目标目录不可写,或者用了相对路径但脚本工作目录不是你预期的(比如 CLI 和 Web 运行时 getcwd() 不同)。
而用浏览器访问却只看到一堆乱码(实际是 PNG 二进制),是因为没设 Content-Type: image/png。phpqrcode 默认不发 header,得自己补。
- 保存文件时用绝对路径:
__DIR__ . '/qrcode.png',别用./qrcode.png - 确认目录有写权限:
is_writable(__DIR__)先测一下 - 直接输出给浏览器,必须在
QRcode::png()前加:header('Content-Type: image/png'); - 如果用了
QRcode::png($data, $filename),第二个参数非false就不会输出,也不会发 header
自定义尺寸和颜色:别碰底层 image* 函数
想改二维码颜色或加 logo?别去翻 phpqrcode 源码里那些 imagecolorallocate()、imagecopy() 调用——它把绘图逻辑全封死了,硬改极易崩溃,且升级就失效。
正确做法是生成标准二维码后,用 GD 或 Imagick 叠加处理。这样解耦清晰,兼容性也好。
- 生成基础图:
QRcode::png($data, $tmpFile = sys_get_temp_dir() . '/qr.png', QR_ECLEVEL_H, 6); - 再用
imagecreatefrompng()读取,imagecolorset()改色,或imagecopyresized()合并 logo - 注意:改色要遍历像素,简单填色可用
imagefill()配合透明背景,但别指望一键换主题色
真正麻烦的是多语言混合内容 + 高压缩率 + 自定义样式三者叠加,这时候不如换 endroid/qr-code 这类现代组件,phpqrcode 太老,连 Composer autoload 都不原生支持。



















