PHP 識別二維碼/條碼完整指南:php-zbarcode 擴展安裝、ImageMagick/zbar 依賴、掃描實戰
PHP 原生無條碼識別能力,需依賴 C 庫 zbar + 影像處理庫 ImageMagick,再透過 PECL 擴展 php-zbarcode 暴露給 PHP。本文提供 CentOS/Ubuntu 完整編譯安裝步驟、依賴坑點規避、掃描代碼封裝、支援格式說明、效能與替代方案對比。
一、依賴關係圖
PHP Script
↓ (extension)
php-zbarcode (PECL)
↓ (link)
libzbar.so (zbar 庫)
↓ (link)
libMagickWand.so / libMagickCore.so (ImageMagick)
↓
系統圖形庫 (freetype, jpeg, png, tiff...)
二、CentOS 7/8 完整編譯安裝 (避坑版)
# 1. 系統依賴
yum -y install gcc gcc-c++ make cmake autoconf automake libtool \
ImageMagick ImageMagick-devel \
libjpeg-devel libpng-devel libtiff-devel freetype-devel
# 2. 編譯安裝 zbar (官方源版本過舊,建議源碼編譯)
cd /usr/local/src
wget https://sourceforge.net/projects/zbar/files/latest/download -O zbar.tar.bz2
tar xjf zbar.tar.bz2
cd zbar-0.10/
# 關鍵:禁用 GTK/Python/Qt 避免大量桌面依賴拉入
./configure --prefix=/usr/local/zbar \
--without-gtk --without-python --without-qt \
--disable-video --disable-doc
make -j$(nproc)
make install
# 3. 配置動態鏈接庫路徑
echo "/usr/local/zbar/lib" > /etc/ld.so.conf.d/zbar.conf
ldconfig
# 4. pkg-config 讓 phpize 找到 zbar
ln -sf /usr/local/zbar/lib/pkgconfig/zbar.pc /usr/lib64/pkgconfig/zbar.pc
# 或 export PKG_CONFIG_PATH=/usr/local/zbar/lib/pkgconfig:$PKG_CONFIG_PATH
# 5. 安裝 php-zbarcode
cd /usr/local/src
wget https://pecl.php.net/get/zbarcode-0.1.2.tgz
tar xzf zbarcode-0.1.2.tgz
cd zbarcode-0.1.2
phpize
./configure --with-php-config=/usr/bin/php-config --with-zbarcode=/usr/local/zbar
make -j$(nproc)
make install
# 6. 啟用擴展
echo "extension=zbarcode.so" > /etc/php.d/zbarcode.ini
# 或編輯 php.ini
# 7. 驗證
php -m | grep zbarcode
php -r 'var_dump(extension_loaded("zbarcode"));'
?>
三、Ubuntu/Debian 快速安裝 (apt 版)
apt-get update
apt-get install -y libzbar-dev libmagickwand-dev php-dev pkg-config
pecl install zbarcode
echo "extension=zbarcode.so" > /etc/php/8.x/mods-available/zbarcode.ini
phpenmod zbarcode
systemctl restart php8.x-fpm
四、PHP 掃描代碼封裝
<?php
class BarcodeScanner
{
/** 掃描圖片檔案,返回所有識別結果陣列
* @return array[] ['type'=>string, 'data'=>string, 'quality'=>int] */
public static function scanFile(string $imagePath): array
{
if (!extension_loaded('zbarcode')) {
throw new \RuntimeException('zbarcode extension not loaded');
}
if (!file_exists($imagePath)) {
throw new \InvalidArgumentException("Image not found: $imagePath");
}
$image = new ZBarCodeImage($imagePath);
$scanner = new ZBarCodeScanner();
$results = $scanner->scan($image);
$formatted = [];
foreach ($results as $r) {
$formatted[] = [
'type' => $r['type'], // QRCODE, EAN13, CODE128 等
'data' => $r['data'], // 解碼內容
'quality'=> $r['quality'] ?? 0,
];
}
return $formatted;
}
/** 掃描二進位圖片資料 (如上傳 $_FILES['img']['tmp_name']) */
public static function scanBlob(string $blob, string $mime = 'image/png'): array
{
$tmp = tempnam(sys_get_temp_dir(), 'zbar_');
file_put_contents($tmp, $blob);
try {
return self::scanFile($tmp);
} finally {
@unlink($tmp);
}
}
}
// 使用範例
$results = BarcodeScanner::scanFile('./test_qrcode.png');
foreach ($results as $r) {
echo "類型: {$r['type']} | 內容: {$r['data']} | 品質: {$r['quality']}
";
}
// 輸出範例:
// 類型: QRCODE | 內容: https://example.com | 品質: 85
// 類型: EAN13 | 內容: 6901234567892 | 品質: 92
?>
五、支援條碼類型 (zbar 0.10+)
| 類型常數 | 說明 | 典型場景 |
| QRCODE | QR Code 二維碼 | 網址、名片、支付 |
| EAN13 / EAN8 | 商品條碼 (13/8 位) | 超市商品 |
| UPCA / UPCE | 美國通用產品碼 | 北美商品 |
| CODE128 | 高密度字母數字條碼 | 物流、倉儲 |
| CODE39 | 字母數字條碼 | 工業標識 |
| CODABAR | 數字+符號條碼 | 圖書館、血庫 |
| I25 / CODE93 | 交換 2/5 碼、Code 93 | 特定行業 |
| PDF417 | 堆疊式二維碼 | 駕照、機票 |
六、效能與替代方案對比
| 方案 | 語言 | 速度 (單張) | 部署複雜度 | 支援格式 | 推薦場景 |
| php-zbarcode | C 擴展 | ~5-20ms | 高 (編譯依賴) | 全格式 | 高併發後端掃描 |
| ZXing (Java) | Java | ~10-30ms | 中 (JRE) | 全格式 | 微服務獨立掃描服務 |
| quaggaJS | JS/WASM | ~30-100ms | 低 (純前端) | 主流 1D/2D | 瀏覽器即時掃描 |
| Python zbarlight | Python | ~10-50ms | 中 | 全格式 | Python 技術棧 |
| Cloud API (Google Vision/AWS) | HTTP | ~200-500ms | 極低 | 全格式+OCR | 低頻、需高精度 |
七、常見坑點總結
- zbar configure 必加
--without-gtk --without-python --without-qt:否則拉入桌面環境依賴,編譯極慢且易失敗
- ImageMagick 版本相容: zbar 需 MagickWand API,ImageMagick 6/7 皆可,但
pkg-config --libs MagickWand 路徑需正確
- PHP 版本匹配: phpize 必須屬於目標 PHP (如
/usr/bin/phpize vs /usr/local/php/bin/phpize)
- Thread Safety: PHP ZTS (Thread Safe) 版需 zbar 亦為線程安全編譯,建議統一用 NTS (Non-Thread Safe)
- 大圖預處理: 掃描前用 ImageMagick 縮放/銳化/二值化,可大幅提高識別率