跳到內容

契約 / 條碼

條碼領域包含四項合約:一個 1D 編碼器、一個 2D 編碼器、一個可透過 registry(註冊表)探索的通用編碼器,以及一個 GS1 資料剖析器。它們定義編碼器必須符合的介面形狀。各符號體系(symbology)的實作則會依這些合約註冊。

Terminal window
composer require nextpdf/core:^3

條碼編碼器會將一段 payload(負載)字串轉換為由模組格構成的矩陣,再交由 PDF writer 繪製。NextPDF 依維度拆分這組合約。Barcode1DEncoderInterface 負責編碼線性符號體系,例如 Code 128、EAN-13,並回傳一個 BarcodeData 值物件。Barcode2DEncoderInterface 負責編碼矩陣符號體系,例如 QR Code、Data Matrix。它會回傳一個 Barcode2DData 值物件,並附帶一份 options 對應表,用於傳遞符號體系專屬參數,例如錯誤更正等級。

BarcodeEncoderInterface 是通用服務供應者合約。任何可透過 BarcodeEncoderRegistry 探索的 2D 編碼器都會實作它。這份合約會回傳單色的 Barcode2DData 或彩色的 BarcodeColorData 矩陣,因此已註冊的編碼器不需要另一個 interface,也能產生彩色符號。除建構期設定外,編碼器預期應維持無狀態。registry 對每個已註冊型別只交付一個共用實例,因此任何跨呼叫保留的狀態都會是缺陷。

Gs1DataParserInterface 是結構化資料合約。它會將一段 GS1 元素字串剖析為具型別的物件,再把該物件重新編碼成 QR Code、Data Matrix 或 Code 128 載體。這會將 GS1 文法與符號體系分離。剖析器只會驗證一次 Application Identifier。各載體專屬的方法會格式化同一份已剖析的結構,以對應每個目標。這四份合約都是 stableBarcodeEncoderInterface 自 3.0.0 起穩定;其餘自 1.0.0 起穩定。新方法只會隨附預設實作一併推出。

型別種類主要成員穩定度自版本
Barcode1DEncoderInterface介面encode(string): BarcodeData穩定1.0.0
Barcode2DEncoderInterface介面encode(string, array): Barcode2DData穩定1.0.0
BarcodeEncoderInterface介面encode(string, array): Barcode2DData|BarcodeColorData穩定3.0.0
Gs1DataParserInterface介面parse(), encodeForQrCode(), encodeForDataMatrix(), encodeForCode128()穩定1.0.0

2D 合約上的 $options 陣列屬於符號體系專屬設定(例如 QR Code 的錯誤更正等級)。合約不會約束它的鍵。每個已註冊的編碼器都會自行記載自己的選項集。

examples/10-barcodes.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Barcode\Barcode2DType;
use NextPDF\Barcode\BarcodeType;
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Barcode Examples');
$doc->addPage();
$doc->setFont('helvetica', '', 10);
$doc->cell(0, 6, 'Code 128:', newLine: true);
$doc->write1DBarcode('NEXTPDF-2026', BarcodeType::C128, x: 15, y: null, w: 80, h: 20);
$doc->ln(28);
$doc->cell(0, 6, 'QR Code (URL):', newLine: true);
$doc->write2DBarcode('https://nextpdf.dev', Barcode2DType::QRCode, x: 15, y: null, w: 40, h: 40);
$doc->save(__DIR__ . '/output/10-barcodes.pdf');

write1DBarcode()write2DBarcode() 會透過 registry resolve(解析)出編碼器。應用程式碼很少直接接觸這些合約;它只需指名一種符號體系,再由 registry 提供對應的編碼器。

examples/contracts/barcode-production.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\Barcode2DEncoderInterface;
use NextPDF\Contracts\Gs1DataParserInterface;
use NextPDF\Exception\BarcodeException;
use Psr\Log\LoggerInterface;
final readonly class Gs1LabelService
{
public function __construct(
private Gs1DataParserInterface $parser,
private Barcode2DEncoderInterface $dataMatrix,
private LoggerInterface $logger,
) {}
/**
* Parse a GS1 element string and encode it as a Data Matrix.
*
* @param string $elementString A GS1 element string with Application Identifiers.
*/
public function encodeLabel(string $elementString): \NextPDF\Barcode\Barcode2DData
{
try {
$parsed = $this->parser->parse($elementString);
$payload = $this->parser->encodeForDataMatrix($parsed);
return $this->dataMatrix->encode($payload, ['errorCorrection' => 'high']);
} catch (BarcodeException $e) {
$this->logger->error('GS1 label encoding failed', [
'error' => $e->getMessage(),
]);
throw $e;
}
}
}

這個服務相依於剖析器與編碼器合約。catch 區塊會記錄並重新拋出特定的 BarcodeException,絕不拋出裸 \Exception

  • 已註冊的編碼器是共用實例。在編碼器上儲存跨呼叫狀態,會破壞並行繪製。請讓編碼器除了建構式設定之外維持無狀態。
  • BarcodeEncoderInterface::encode() 可能回傳彩色或單色資料。使用它的程式碼必須同時處理 Barcode2DDataBarcodeColorData,不可假設一定是單色。
  • 2D 的 $options 陣列不會由合約驗證。大多數編碼器會默默忽略未知鍵。請對照編碼器自身文件核對鍵名。
  • GS1 剖析的文法要求很嚴格。帶有未知 Application Identifier 的元素字串會引發 BarcodeException,而不是產生不完整的剖析結果。請在上游驗證輸入。
  • 1D 與 2D 合約不可互換。把 QR payload 傳給 1D 編碼器會產生無效符號。registry 會依符號體系型別路由,因此請優先使用 registry,而不是直接呼叫合約。

編碼成本會隨 payload 長度與目標矩陣大小而變,與合約本身無關。一段簡短的 Code 128 payload 可在數微秒內完成編碼。高錯誤更正的密集 QR Code 是最吃重的 2D 案例。它仍遠低於多符號範例頁的 performance_budget(1500 ms 牆鐘時間與 64 MB 尖峰記憶體)。矩陣只會計算一次,再以 PDF 運算子繪製。可重現性是 bitwise,因為相同的 payload 與選項一定會產生相同的模組矩陣。registry 查找是 O(1)。真正的工作量在於符號體系演算法。

條碼 payload 經常受攻擊者影響,例如被掃描的 URL、序號或追蹤碼。這些合約只編碼位元組,不解讀位元組內容。編碼了惡意 URL 的 QR Code 仍是有效的 QR Code,因此 payload 是否可信任,是消費端的責任,而不是編碼器的責任。請在編碼前先約束 payload 長度,以限制矩陣大小,並避免因符號過大造成阻斷服務(DoS)。GS1 剖析器會拒絕格式錯誤的 Application Identifier,這會移除一個注入面。它不會查核有效欄位的語意內容。凡是解碼後的條碼資料重新進入應用程式之處,都應將它視為不可信任的輸入。

主張標準參照
QR Code 符號遵循 QR Code 矩陣符號體系規格。ISO/IEC 18004QR Code 符號體系
Data Matrix 符號遵循 Data Matrix 符號體系規格。ISO/IEC 16022Data Matrix 符號體系
Code 128 符號遵循 Code 128 線性符號體系規格。ISO/IEC 15417Code 128 符號體系
GS1 元素字串會依 GS1 Application Identifier 文法剖析。GS1 一般規格Application Identifier(應用識別碼)

這些標準以編號與條款引用。它們並未收錄於可驗證的引用語料庫中,因此沒有記錄任何 reference_id。引擎會改寫該需求內容,並引用其來源。請查閱已發布的標準,以取得權威的編碼規則。

核心會定義並凍結編碼器合約,並隨附常見符號體系。Pro 版與 Enterprise 版會針對同一個 BarcodeEncoderInterface 註冊一組擴充編碼器,以支援額外的條碼符號體系;因此商業部署無需變更 API,就能取得更廣的符號體系覆蓋。核心會透過 BarcodeEncoderRegistry 解析已註冊的編碼器。各版本之間的合約介面完全相同。