gd扩展未启用或png支持缺失会导致imagepng()等函数报错或静默失败;中文需urlencode后传入;输出前须清理缓冲并设置content-type;字体路径必须存在且可读。

GD 扩展没启用或 PNG 支持缺失
PHP 8.5.5 本身不自带图像处理能力,imagepng() 这类函数来自 GD 扩展。如果没启用,调用 QRcode::png() 或 QrCode->writeString() 会直接报 Call to undefined function imagepng(),或者静默失败(比如输出乱码、空白页、纯文本)。
验证方式很简单:
-
php -m | grep gd—— 看是否在扩展列表里 - 代码里加:
var_dump(extension_loaded('gd') && function_exists('imagepng'));
常见漏点:
- Ubuntu/Debian 装了
php-gd却没装php-freetype,导致带文字的二维码崩(imagettftext()不可用) - Alpine Linux 默认 GD 编译不含 PNG 支持,得重装:
apk add php7-gd php7-png - Windows 下
php.ini里启用了extension=php_gd2.dll,但实际 DLL 缺依赖(如libpng16.dll未在 PATH 中)
中文内容没做 URL 编码或 UTF-8 强制声明
endroid/qr-code 默认按 Latin-1 解释输入,直接传 '张三' 这种 UTF-8 字符串,扫码器解码时大概率显示 %E5%BC%A0%E4%B8%89 或乱码方块——不是库坏了,是编码层没对齐。
正确做法分两步:
- 内容传入前做
urlencode($str),例如:new QrCode(urlencode('张三')) - 若用 Builder 模式,必须显式指定编码:
->encoding(new Encoding('UTF-8'))
注意:仅用 mb_convert_encoding($str, 'UTF-8') 不够,它只转字节流,不解决 QR 标准对字符集无标识的问题;URL 编码才是 QR 解码器能普遍识别的兼容方案。
输出前已有内容干扰二进制流
浏览器看到一堆乱码(其实是 PNG 二进制被 HTML/空格/BOM 截断),基本就是 header 已发送。PHP 8.5.5 对输出缓冲更敏感,尤其在 ThinkPHP 或 Laravel 环境下,路由中间件、日志记录、甚至文件开头的 BOM 都可能触发 Headers already sent 错误。
排查和修复要点:
- 生成二维码的脚本必须是独立入口,不要
require其他含 echo、HTML 或空行的文件 - 用编辑器确认文件是「UTF-8 无 BOM」格式(VS Code / PHPStorm 右下角可查)
- 加兜底清理:
ob_end_clean(); header('Content-Type: image/png');放在writeString()或png()前 - 写文件时不用管 header,但路径必须绝对:
__DIR__ . '/qrcode.png',别用./qrcode.png
字体路径错误或不可读导致文字区域空白
如果你在二维码上加 label、title 或 logo 文字,却只看到图、不见字,大概率是字体路径失效。imagettftext() 对路径极其严格:文件必须存在、可读、且是真实 .ttf 文件(不是 .otf 或链接)。
验证方法很直接:
-
var_dump(file_exists($fontPath), is_readable($fontPath));—— 两个都得是true - 临时注释掉
->setLabel()或->setLogoPath(),看图片能否正常生成 - 别用
C:\Windows\Fonts\simhei.ttf这种 Windows 路径部署到 Linux 服务器
推荐写法:__DIR__ . '/fonts/simhei.ttf',并确保该文件随代码一起部署,权限为 644。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











