契约 / 条码
条码领域包含四项合约:一个 1D 编码器、一个 2D 编码器、一个可通过 registry(注册表)发现的通用编码器,以及一个 GS1 数据解析器。它们定义了编码器必须满足的接口形态。各符号体系(symbology)的实现会向这些合约注册。
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。各载体专属方法会把同一份已解析结构格式化,以适配每个目标。这四份合约都是 stable。BarcodeEncoderInterface 自 3.0.0 起稳定;其余则自 1.0.0 起稳定。新方法只会随默认实现一并推出。
API 接口
标题为“API 接口”的章节| 类型 | 种类 | 主要成员 | 稳定度 | 自版本 |
|---|---|---|---|---|
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 的错误更正等级)。合约并不约束它的键。每个已注册的编码器都会自行记录其选项集。
代码示例——快速上手
标题为“代码示例——快速上手”的章节<?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 提供对应的编码器。
代码示例——正式环境
标题为“代码示例——正式环境”的章节<?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()可能返回彩色或单色数据。 使用它的代码必须同时处理Barcode2DData与BarcodeColorData,不可假设一定是单色。- 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 18004 | QR Code 符号体系 |
| Data Matrix 符号遵循 Data Matrix 符号体系规格。 | ISO/IEC 16022 | Data Matrix 符号体系 |
| Code 128 符号遵循 Code 128 线性符号体系规格。 | ISO/IEC 15417 | Code 128 符号体系 |
| GS1 元素字符串会依 GS1 Application Identifier 文法解析。 | GS1 一般规格 | Application Identifier(应用识别码) |
这些标准以编号与条款引用。它们并未收录于可验证的引用语料库中,因此没有记录任何 reference_id。引擎会改写该需求的内容,并引用其来源。请查阅已发布的标准,以取得权威的编码规则。
商业脉络
标题为“商业脉络”的章节核心定义并冻结编码器合约,并随附常见的符号体系。Pro 版与 Enterprise 版会针对同一个 BarcodeEncoderInterface 注册一组扩展编码器,以支持额外的条码符号体系,因此商业部署无需变更 API 就能获得更广的符号体系覆盖。核心会通过 BarcodeEncoderRegistry 解析出已注册的编码器。各版本之间的合约接口完全相同。
另请参阅
标题为“另请参阅”的章节- 合约:41 个公开接口(SPI)——SPI 总览与稳定度层级。
- 条码——向这些合约注册的符号体系实现。
- 合约/文档——绘制已编码矩阵的
PdfDocumentInterface。 - 图形——绘制条码模块格的绘图层。
- 例外——在 GS1 输入格式错误时抛出的
BarcodeException。