首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 生成二維碼中文亂碼根因分析與三大主流庫完整整合指南

     編輯:PHP 相關知識

PHP 生成二維碼掃描後中文顯示亂碼,核心原因通常是 **編碼不一致**(生成端 UTF-8、掃描端預期 GBK/其他)或 **vCard 格式欄位缺失** 導致解析器誤判。本文深度剖析根因、提供三大主流庫整合代碼、並解決 Logo 嵌入與編碼兼容難題。

亂碼根因深度剖析

現象根因驗證方法
Android 掃描 vCard 姓名亂碼vCard 缺少 `ORG` 等關鍵欄位,解析器回退錯誤編碼補全所有 vCard 標準欄位測試
所有掃描器中文亂碼QR Code 內容實際為 GBK/Big5,但掃描器預設 UTF-8用線上解碼工具檢視原始位元組
特定字元(如表情符)消失QR Code 版本過小/錯誤修正等級過高,容量不足升級 Version、降低 Error Correction Level

三大主流 PHP 二維碼庫整合

1. Google Chart API(已停止維護,僅供參考)

<?php
function generateGoogleQR(string $data, int $size = 150, string $level = 'L', int $margin = 0): string {
    $params = http_build_query([
        'chs' => "${size}x{$size}",
        'cht' => 'qr',
        'chl' => $data,
        'choe' => 'UTF-8',      // 強制指定編碼
        'chld' => "$level|$margin",
    ]);
    return "https://chart.googleapis.com/chart?$params";
}

// 使用
echo '<img src="' . generateGoogleQR('中文測試內容') . '" />';
?>
> ⚠️ Google 於 2019 年停止服務,**生產環境勿用**。

2. PHP QR Code (phpqrcode) - 純 PHP 實作、零依賴

# 安裝
composer require endroid/qrcode  # 現代維護分支
# 或下載原版:https://sourceforge.net/projects/phpqrcode/

<?php
require_once 'phpqrcode/qrlib.php';  // 原版入口

// 1. 直接輸出圖片到瀏覽器
QRcode::png('中文內容測試', false, 'L', 4, 2);

// 2. 儲存檔案
QRcode::png('https://example.com?vcard=...', 'qrcode.png', 'M', 6, 2);

// 3. 關鍵:強制 UTF-8 編碼輸入
$data = mb_convert_encoding('中文內容', 'UTF-8', 'auto');
QRcode::png($data, false, 'L', 4);
?>

3. BaconQrCode (現代、PSR-4、支援 Logo 嵌入)

composer require bacon/bacon-qr-code

<?php
use BaconQrCode\Renderer\Image\SvgImageBackEnd;
use BaconQrCode\Renderer\ImageRenderer;
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
use BaconQrCode\Writer;

$writer = new Writer(
    new ImageRenderer(
        new RendererStyle(300),  // 300px
        new SvgImageBackEnd()
    )
);

// 直接輸出 SVG(無損縮放、易嵌入 Logo)
header('Content-Type: image/svg+xml');
echo $writer->writeString('中文測試內容');

// PNG 輸出需額外安裝 imagine/imagine
?>

4. libqrencode C 擴充 (效能最高、需編譯)

# 安裝系統庫
apt-get install libqrencode-dev
# PHP 擴充
pecl install qrencode
# php.ini
extension=qrencode.so

<?php
// 簡單介面
qr_encode('中文內容', 'qrcode.png', 300, 300, 3, QR_ECLEVEL_L);
// 參數:資料、檔名、寬、高、版本、錯誤修正等級
?>

進階:二維碼中央嵌入 Logo (基於 phpqrcode 修改)

<?php
require_once 'phpqrcode/qrlib.php';

function generateQRWithLogo(string $data, string $logoPath, string $outputPath, int $qrSize = 300): bool {
    // 1. 產生基礎 QR Code (較高錯誤修正等級 H 容許 30% 遮擋)
    QRcode::png($data, $outputPath, 'H', 10, 1); // 邊距 1

    // 2. 載入 QR Code 與 Logo
    $qr = imagecreatefrompng($outputPath);
    $logo = imagecreatefromstring(file_get_contents($logoPath));
    if (!$qr || !$logo) return false;

    // 3. 計算置中座標
    $qrW = imagesx($qr);
    $qrH = imagesy($qr);
    $logoW = imagesx($logo);
    $logoH = imagesy($logo);
    
    // Logo 最大佔 QR Code 20% 面積
    $maxLogoW = $qrW * 0.2;
    $maxLogoH = $qrH * 0.2;
    if ($logoW > $maxLogoW || $logoH > $maxLogoH) {
        $scale = min($maxLogoW / $logoW, $maxLogoH / $logoH);
        $logoW = (int)($logoW * $scale);
        $logoH = (int)($logoH * $scale);
        $logo = imagescale($logo, $logoW, $logoH);
    }

    $dstX = ($qrW - $logoW) / 2;
    $dstY = ($qrH - $logoH) / 2;

    // 4. 白色底板(可選,增強對比)
    $white = imagecolorallocate($qr, 255, 255, 255);
    imagefilledrectangle($qr, $dstX-2, $dstY-2, $dstX+$logoW+2, $dstY+$logoH+2, $white);

    // 5. 合成 (支援透明度)
    imagealphablending($qr, true);
    imagesavealpha($qr, true);
    imagecopy($qr, $logo, $dstX, $dstY, 0, 0, $logoW, $logoH);

    // 6. 輸出
    imagepng($qr, $outputPath);
    imagedestroy($qr);
    imagedestroy($logo);
    return true;
}

// 使用
generateQRWithLogo('https://example.com', 'logo.png', 'qr_with_logo.png');
?>

vCard 格式完整範本(解決 Android 亂碼關鍵)

<?php
function buildVCard(array $data): string {
    $required = [
        'FN' => $data['name'] ?? '',           // 完整姓名 (必填)
        'ORG' => $data['company'] ?? ' ',      // 公司/組織 (關鍵:防亂碼必填)
        'TEL;TYPE=WORK,VOICE' => $data['tel'] ?? '',
        'EMAIL' => $data['email'] ?? '',
        'URL' => $data['website'] ?? '',
        'ADR;TYPE=WORK' => $data['address'] ?? '',
        'TITLE' => $data['title'] ?? '',
        'NOTE' => $data['note'] ?? '',
    ];
    
    $lines = ['BEGIN:VCARD', 'VERSION:3.0'];
    foreach ($required as $key => $val) {
        if ($val !== '') {
            $lines[] = "$key:" . str_replace(['\n', '\r', ':'], ['\\n', '\\r', '\\:'], $val);
        }
    }
    $lines[] = 'END:VCARD';
    return implode("\r\n", $lines); // vCard 標準換行 CRLF
}

// 生成含 Logo 的 vCard QR Code
$vcard = buildVCard([
    'name' => '張三豐',
    'company' => '武當派',        // 必填!
    'tel' => '+886-2-1234567',
    'email' => 'zhang@wudang.org',
]);
generateQRWithLogo($vcard, 'logo.png', 'vcard_qr.png');
?>

編碼兼容性最佳實踐清單

  1. 輸入資料統一 UTF-8:`mb_convert_encoding($data, 'UTF-8', 'auto')`。
  2. vCard 必填 ORG 欄位:哪怕是空格 `ORG: ` 也要保留。
  3. 錯誤修正等級選 H:嵌入 Logo 時必須用 `H` (30% 容錯)。
  4. 版本自動計算:庫會自動升級 Version 容納資料,勿手動限制。
  5. 測試矩陣:Android (Google Lens/微信/支付寶)、iOS (相機/微信)、專業掃描槍。

採用 BaconQrCode 或 phpqrcode 搭配完整 vCard 模板與 H 級錯誤修正,能徹底解決中文亂碼、Logo 嵌入、跨平台掃描兼容三大核心痛點。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved