phpqrcode无需安装扩展,下载qrlib.php和qrimg.php并require_once引入即可使用;中文需转GB2312编码;QRcode::png()参数顺序为$text、$outfile、$level、$size、$margin;带logo需GD库二次合成。

phpqrcode 扩展不装也能用,但得手动引入文件
很多人卡在第一步:composer install phpqrcode 失败,或者服务器没权限装扩展。其实 phpqrcode 本质就是一串纯 PHP 文件,不需要编译安装。下载官方源码(比如从 GitHub 拉 phpqrcode/qrimg.php 和 phpqrcode/qrlib.php),放进项目目录,require_once 'qrlib.php'; 就能开始调用。
常见错误是只引入了 qrimg.php 却漏掉 qrlib.php,运行时报 Class 'QRcode' not found。这两个文件有依赖关系,必须都加载。
- 推荐直接用
qrlib.php,它封装了核心逻辑;qrimg.php只是输出图片的快捷包装 - 如果项目用了 Composer,可以用
endroid/qr-code替代(更现代),但那是另一个库,和phpqrcode不兼容 - 注意文件路径——
require_once的路径写错,会静默失败或报failed to open stream
生成二维码时中文乱码?默认不支持 UTF-8
phpqrcode 原生只处理 ISO-8859-1 编码,直接传中文字符串会变成方块或问号。不是字体问题,是编码没转。
解决方法是把中文先用 iconv('UTF-8', 'GB2312//IGNORE', $text) 或 mb_convert_encoding($text, 'GB2312', 'UTF-8') 转成 GB2312(兼容性最好),再喂给 QRcode::png()。
立即学习“PHP免费学习笔记(深入)”;
- 别用
utf8_encode(),它只对 Latin-1 字符有效,对中文无效 - 如果内容含 emoji 或生僻字,GB2312 也扛不住,这时建议换库(如
endroid/qr-code)或改用 base64 编码后传入再前端解码 - 测试时用
bin2hex($text)看原始字节,确认是否真乱码,还是浏览器渲染问题
QRcode::png() 参数顺序容易搞反,第四个参数才是容错级别
函数签名是 QRcode::png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4)。新手常把 $size(模块大小)和 $margin(白边宽度)记混,结果二维码要么小得看不清,要么撑满整个图片没留白。
容错级别 $level 有四个常量:QR_ECLEVEL_L(约 7%)、QR_ECLEVEL_M(15%,默认)、QR_ECLEVEL_Q(25%)、QR_ECLEVEL_H(30%)。选太高会让二维码“糊”,尤其内容短时反而识别率下降。
-
$size = 1是最小单位,但手机扫描可能失败;$size = 4更稳妥 -
$margin = 0会导致扫码器误判边界,微信/支付宝都要求至少 4 个模块空白 - 如果要输出到浏览器而非文件,
$outfile必须为false,且前面不能有任何输出(包括空格、BOM),否则报Cannot modify header information
生成带 logo 的二维码?phpqrcode 不支持,得自己合成
phpqrcode 本身不提供“打水印”或“嵌入图片”功能。所谓“带 logo 的二维码”,其实是两步:先生成纯二维码 PNG,再用 GD 或 Imagick 把 logo 图片贴上去。
关键点在于 logo 尺寸不能太大——一般不超过二维码面积的 20%,否则中心模块被遮挡,大部分扫码器无法识别。实测微信识别容忍度最低,logo 边长建议 ≤ 二维码边长 × 0.15。
- 用
imagecreatefrompng()加载二维码图,imagecreatefromjpeg()加载 logo,再用imagecopyresized()合成 - 别用
imagecopymerge(),透明通道会出问题;logo PNG 必须带 alpha 通道且背景透明 - 合成后记得
imagedestroy()释放资源,不然内存涨得快,尤其批量生成时











