二維碼生成是常見需求,帶 Logo 更具品牌識別度。本文深度對比後端 phpqrcode 與前端 qrcode.js 兩大主流方案,從原理、實現、性能、部署、用戶體驗全維度分析,助你選型。
| 維度 | phpqrcode (後端) | qrcode.js (前端) |
|---|---|---|
| 運算位置 | 服務器 CPU | 客戶端 GPU/CPU |
| Logo 來源 | 服務器文件系統 (需上傳) | 用戶本地選擇 (無上傳) |
| 生成速度 | 網絡延遲 + 服務器排隊 | 即時 (毫秒級) |
| 併發壓力 | 高 (圖片處理消耗內存/CPU) | 零 (分散到客戶端) |
| 存儲成本 | 需保存生成文件 (需定期清理) | 無 (用戶自行保存/截圖) |
| 離線可用 | 否 | 是 (Service Worker 緩存) |
| 自定義樣式 | 困難 (需修改 PHP 代碼) | 靈活 (CSS/Canvas API 任意繪製) |
| SEO/分享 | 直接圖片 URL 利於分享 | 需截圖或導出後上傳 |
| 安全性 | 服務器可控內容 | 用戶可構造任意內容 |
| 適用場景 | 營銷海報、名片、固定二維碼批量生成 | 用戶個性化生成、臨時分享、互動營銷 |
// phpqrcode
QRcode::png($data, $file, 'H', $size); // L/M/Q/H,H 最高容錯 30%
// qrcode.js
correctLevel: QRCode.CorrectLevel.H // 同理
// Logo 面積建議 ≤ 20% 總面積,居中放置,避開定位點 (三個角) 和定時序列
// 文件 → Base64
reader.readAsDataURL(file); // 結果: "data:image/png;base64,iVBORw0KGgo..."
// Base64 → Image 對象
const img = new Image();
img.src = base64String; // 直接賦值 src
// Canvas 導出 Base64
canvas.toDataURL('image/png', 1.0); // 質量 1.0
canvas.toBlob(blob => { /* 上傳 */ }, 'image/png');
// 1. 復用 GD 資源
$qrBase = imagecreatefromstring(file_get_contents('base_qr.png'));
$logo = imagecreatefromstring(file_get_contents('logo.png'));
// 2. 並行處理 (Swoole/多進程)
$pm = new ProcessManager(10);
foreach ($dataList as $data) {
$pm->addTask(function() use ($data, $qrBase, $logo) {
$qr = clone $qrBase; // GD 不支援 clone,需重新生成或 imagecopy
// ... 合成邏輯
imagepng($qr, "output/{$data['id']}.png");
});
}
$pm->waitAll();
需要批量生成固定二維碼? → 是 → phpqrcode (後端)
用戶需要自定義內容/Logo? → 是 → qrcode.js (前端)
高併發公開 API? → 是 → qrcode.js (前端) + 可選後端簽名驗證
營銷海報合成? → 是 → phpqrcode (後端) + GD/Imagick 合成
離線/弱網環境? → 是 → qrcode.js (前端) + PWA
嵌入式設備/無前端? → 是 → phpqrcode (後端)
沒有銀彈,只有適合場景的選擇。理解雙方原理與權衡,才能在產品演進中做出正確架構決策。