在Web开发中,经常需要把一段文本、网址或者用户信息编码成二维码并立刻展示给用户,而不是先保存成文件再返回。PHP借助成熟的第三方库,可以在服务端内存中生成二维码图像,并通过设置HTTP响应头直接输出二进制流,浏览器收到后就会渲染成一张可扫码的图片。

一、使用endroid/qr-code库生成并输出
endroid/qr-code是目前PHP生态中最常用的二维码生成库之一,它不依赖外部服务,纯PHP实现,支持PNG、SVG等多种格式。通过Composer安装后,我们可以用很少的代码完成内存生成与输出。
下面示例展示了如何在不写文件的情况下,将一段网址转为PNG二维码并直接发送到浏览器。关键点在于调用writeString方法获取二进制内容,并在echo之前设置正确的Content-Type。
<?php
require 'vendor/autoload.php';
use EndroidQrCodeQrCode;
use EndroidQrCodeWriterPngWriter;
// 要编码的内容,必须是UTF-8字符串
$text = 'https://ipipp.com/php-qr-demo';
$qrCode = new QrCode($text);
$qrCode->setSize(300);
$qrCode->setMargin(10);
$writer = new PngWriter();
$result = $writer->write($qrCode);
// 设置响应头,告诉浏览器这是图片
header('Content-Type: ' . $result->getMimeType());
// 直接输出二进制流
echo $result->getString();
exit;
上述代码中,setSize控制像素尺寸,setMargin控制静区宽度。如果内容包含中文,只要源文件本身是UTF-8且无BOM格式,库会自动处理,不会乱码。
这种方式的优势是零磁盘IO,特别适合高并发的核销码、临时登录码场景。劣势是每次请求都要实时计算,若二维码内容复杂且访问量大,可考虑加一层Redis缓存二进制结果。
二、使用PHP QR Code原生库输出
除了Composer库,还有一个经典轻量项目叫PHP QR Code,它只有一个phpqrcode.php文件,适合不便使用Composer的旧项目。该库提供了QRcode::png方法,其第四个参数如果传false,就不会保存文件而是直接输出。
以下示例演示了用该库直接输出图片。注意它内部已经发送了header,因此我们的脚本在调用前不能有任何输出,包括空格和BOM。
<?php // 引入单一文件库 require 'phpqrcode.php'; $text = '订单号:88881234'; // 参数: 内容, 文件路径(false表示输出), 纠错级别, 尺寸, 边距 QRcode::png($text, false, QR_ECLEVEL_L, 6, 2); exit;
QR_ECLEVEL_L代表低纠错,尺寸参数6表示每个黑块占6像素。因为该方法自己会发图片头,所以我们不需要手动header,但必须保证require之前没有任何字符输出。
这种方案的优点是部署极简,缺点是代码较老,对PHP8的支持需要轻微修改,且默认不支持SVG。若只是内部系统临时用用,它依然够用。
三、输出时的常见坑与排查
直接输出图片最怕出现“图片无法显示”或浏览器下载到破损文件。绝大多数情况是因为在header或二进制前混入了多余输出,比如PHP文件末尾的换行、UTF-8 BOM头,或者错误日志被打印到了页面。
可以用ob_clean清空缓冲区来兜底。如下片段展示了一个安全的输出包装写法,先清缓冲再发头,避免历史输出污染图像流。
<?php
ob_clean();
header('Content-Type: image/png');
echo $binary;
exit;
另一个坑是浏览器缓存。若接口既输出图片又被AJAX误调,可能拿到的是旧图。可在header中加Cache-Control: no-store来禁止缓存。这样每次扫码都拿到最新内容,适合动态令牌类需求。
四、对比与选型建议
我们将两种主流方案在几个维度做简单对比,方便根据实际项目选择。
| 方案 | 安装方式 | 输出灵活性 | 维护状态 |
|---|---|---|---|
| endroid/qr-code | Composer | 高,支持多格式与自定义颜色 | 活跃 |
| PHP QR Code | 单文件引入 | 低,仅基础PNG | 基本停更 |
如果是新项目,建议直接用endroid/qr-code,它不仅能直接输出,还能把二维码嵌入到已有的GD图像里,实现带Logo的码。老项目改造若不想动依赖,单文件库是最小成本方案。
无论哪种方式,直接输出都比写临时文件再readfile更干净。只要控制好字符编码和输出纯净度,PHP生成并输出二维码图片就是一件轻松的事。