最省事的PHP动态生成二维码方案是用endroid/qr-code:支持PHP 7.4+、PNG/SVG输出、加logo、调色、设容错,不强制依赖GD(fallback兼容),中文需UTF-8编码+高纠错或urlencode,网页中可用writeString()直接输出图片流。

用 endroid/qr-code 生成二维码最省事
PHP 动态网站里生成二维码,别自己造轮子。推荐直接用 Composer 安装 endroid/qr-code —— 它支持 PHP 7.4+,输出 PNG/SVG,还能加 logo、调颜色、设容错等级,而且不依赖 GD 扩展(默认用 imagick,但 fallback 到 GD 也行)。
安装命令:
composer require endroid/qr-code
基础用法示例(生成带链接的 PNG):
$qrCode = new \Endroid\QrCode\QrCode('https://example.com');
$qrCode->writeFile(__DIR__.'/qrcode.png');
注意点:
- 如果服务器没装
imagick,它会自动退回到 GD,但 GD 不支持 SVG 输出 -
writeFile()要求目标目录有写权限,否则报Unable to write image - 中文内容必须 UTF-8 编码,否则乱码或报错
Invalid data
中文内容二维码生成失败?检查编码和纠错等级
直接传中文字符串给 QrCode 构造函数常失败,不是语法错,是 QR 标准对非 ASCII 字符敏感。根本原因是默认使用 Byte 模式编码,但部分中文 UTF-8 字节序列会触发容错不足。
立即学习“PHP免费学习笔记(深入)”;
解决方法:
远航CMS(yhcms)是一套基于PHP+MYSQL为核心开发的专业营销型企业建站系统。是国内首家免费+开源自带分站系统的php内容管理系统。长期以来不断的完善、创新,远航CMS会为您带来全新的体验!产品十大优势:模板分离:模板程序分离,深度二次开发三网合一:电脑/手机/微信 多终端访问自定义广告:图片/文字/动画定时发布:SEO维护,无需人工值守多词生成:栏目关键词多方案生成SEO设置:自定义U
- 显式设置编码模式为
QrCode::OUTPUT_TYPE_PNG并提高纠错等级:$qrCode = new \Endroid\QrCode\QrCode('你好世界');
$qrCode->setEncoding('UTF-8');
$qrCode->setErrorCorrectionLevel(\Endroid\QrCode\ErrorCorrectionLevel::HIGH); - 更稳妥的是先
urlencode()再生成,扫码后前端再 decode:$qrCode = new \Endroid\QrCode\QrCode(urlencode('你好世界')); - 避免用
json_encode()包裹中文再塞进去——多一层转义反而容易超长度限制
在网页中动态输出二维码图片(不存文件)
很多场景不需要保存 PNG 文件,而是直接 echo 图片流返回浏览器。这时候不能用 writeFile(),得用 writeString() 配合 header。
关键三步:
- 清空输出缓冲:
ob_clean(); - 设响应头:
header('Content-Type: image/png');
header('Content-Disposition: inline; filename="qrcode.png"'); - 输出二进制流:
echo $qrCode->writeString();
常见坑:
- 前面有
echo、var_dump或空白字符,会导致Cannot modify header information - 如果用了 Twig 或其他模板引擎,确保这个二维码脚本是独立入口(比如
/qrcode.php?text=xxx),别混在 HTML 模板里输出 - 移动端扫码时,建议加
header('Cache-Control: no-store, no-cache');防止 CDN 缓存旧码
生成带 Logo 的二维码要注意尺寸和透明度
往二维码中间嵌入 logo 很常见,但 endroid/qr-code 默认不支持。得手动用 GD 或 Imagick 合成——这意味着你必须控制好尺寸比例,否则 logo 会糊或遮挡关键定位点。
实操要点:
- 二维码最小尺寸建议 ≥ 300×300 px,logo 宽高不超过二维码的 25%
- logo 必须是 PNG 且带透明背景,JPG 会盖住底层二维码导致扫不出
- 合成前,先用
$qrCode->setSize(300)固定大小,再用imagecreatefrompng()加载 logo,最后imagecopyresized()居中贴图 - 别试图在
QrCode对象上链式调用setLogoPath()—— 这个方法是旧版 API,新版已移除
复杂点在于:logo 尺寸、位置、透明通道、二维码容错等级三者必须协同。哪怕只调高一级纠错(MEDIUM → HIGH),就能显著提升带 logo 后的扫码成功率。










