Zum Inhalt springen

Contracts / Barcode

Die Barcode-Domäne umfasst vier Contracts: einen 1D-Encoder, einen 2D-Encoder, einen generischen, über die Registry auffindbaren Encoder und einen GS1-Datenparser. Sie definieren die Form, die ein Encoder erfüllen muss. Symbologie-Implementierungen registrieren sich für diese Contracts.

Terminal-Fenster
composer require nextpdf/core:^3

Ein Barcode-Encoder wandelt einen Payload-String in eine Matrix aus Modulen um, die der PDF-Writer zeichnet. NextPDF unterteilt den Contract nach Dimensionalität. Barcode1DEncoderInterface kodiert lineare Symbologien — Code 128, EAN-13 und ähnliche — und liefert ein BarcodeData-Wertobjekt. Barcode2DEncoderInterface kodiert Matrix-Symbologien — QR Code, Data Matrix. Es liefert ein Barcode2DData-Wertobjekt mit einer Options-Map für symbologiespezifische Parameter wie die Fehlerkorrekturstufe.

BarcodeEncoderInterface ist der generische Service-Provider-Contract. Jeder über BarcodeEncoderRegistry auffindbare 2D-Encoder implementiert ihn. Der Contract liefert entweder eine monochrome Barcode2DData oder eine farbige BarcodeColorData-Matrix, sodass ein registrierter Encoder ein farbiges Symbol ohne separate Schnittstelle erzeugen kann. Von Encodern wird erwartet, dass sie über die Konstruktorkonfiguration hinaus zustandslos sind. Die Registry stellt pro registriertem Typ eine gemeinsam genutzte Instanz bereit; aufrufbezogener Zustand wäre daher ein Defekt.

Gs1DataParserInterface ist der Contract für strukturierte Daten. Er parst einen GS1-Element-String in ein typisiertes Objekt und kodiert dieses Objekt anschließend erneut für einen QR-Code-, Data-Matrix- oder Code-128-Träger. So bleibt die GS1-Grammatik von der Symbologie getrennt. Der Parser validiert Application Identifiers ein einziges Mal. Die trägerspezifischen Methoden formatieren dieselbe geparste Struktur für jedes Ziel. Die vier Contracts sind stable. BarcodeEncoderInterface ist seit 3.0.0 stable; die übrigen seit 1.0.0. Neue Methoden kommen nur mit Standardimplementierungen hinzu.

TypArtWichtige MemberStabilitätSeit
Barcode1DEncoderInterfaceinterfaceencode(string): BarcodeDatastable1.0.0
Barcode2DEncoderInterfaceinterfaceencode(string, array): Barcode2DDatastable1.0.0
BarcodeEncoderInterfaceinterfaceencode(string, array): Barcode2DData|BarcodeColorDatastable3.0.0
Gs1DataParserInterfaceinterfaceparse(), encodeForQrCode(), encodeForDataMatrix(), encodeForCode128()stable1.0.0

Das $options-Array der 2D-Contracts ist symbologiespezifisch (zum Beispiel eine Fehlerkorrekturstufe für QR Code). Der Contract schränkt die Schlüssel nicht ein. Jeder registrierte Encoder dokumentiert seine eigene Optionsmenge.

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() und write2DBarcode() lösen einen Encoder über die Registry auf. Anwendungscode greift nur selten direkt auf die Contracts zu. Er benennt eine Symbologie, und die Registry liefert den Encoder.

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;
}
}
}

Der Service hängt von den Parser- und Encoder-Contracts ab. Der catch-Block protokolliert die spezifische BarcodeException und wirft sie erneut, niemals eine bloße \Exception.

  • Ein registrierter Encoder wird gemeinsam genutzt. Zustand pro Aufruf in einem Encoder zu speichern, beschädigt parallele Renderings. Halten Sie Encoder über die Konstruktorkonfiguration hinaus zustandslos.
  • BarcodeEncoderInterface::encode() kann farbige oder monochrome Daten liefern. Code, der diese Daten verarbeitet, muss sowohl Barcode2DData als auch BarcodeColorData behandeln und darf Monochromie nicht voraussetzen.
  • Das 2D-$options-Array wird vom Contract nicht validiert. Ein unbekannter Schlüssel wird von den meisten Encodern stillschweigend ignoriert. Prüfen Sie den Schlüsselnamen anhand der jeweiligen Dokumentation des Encoders.
  • Das GS1-Parsing ist strikt in Bezug auf die Grammatik. Ein Element-String mit einem unbekannten Application Identifier löst eine BarcodeException aus, statt einen partiellen Parse zu erzeugen. Validieren Sie die vorgelagerte Eingabe.
  • 1D- und 2D-Contracts sind nicht austauschbar. Eine QR-Payload, die an einen 1D-Encoder übergeben wird, erzeugt ein ungültiges Symbol. Die Registry leitet nach Symbologie-Typ weiter; bevorzugen Sie daher die Registry gegenüber einem direkten Contract-Aufruf.

Der Aufwand für die Kodierung skaliert mit der Payload-Länge und der Größe der Zielmatrix, nicht mit dem Contract. Eine kurze Code-128-Payload wird in Mikrosekunden kodiert. Ein dicht belegter QR Code mit hoher Fehlerkorrektur ist der schwerste 2D-Fall. Er liegt für die Beispielseite mit mehreren Symbolen dennoch deutlich innerhalb des performance_budget von 1500 ms Wall Time und 64 MB Spitzenverbrauch. Die Matrix wird einmal berechnet und als PDF-Operatoren gezeichnet. Die Reproduzierbarkeit ist bitwise, weil dieselbe Payload und dieselben Optionen immer dieselbe Modulmatrix ergeben. Der Registry-Lookup ist O(1). Der eigentliche Aufwand liegt im Symbologie-Algorithmus.

Barcode-Payloads werden häufig von Angreifern beeinflusst — etwa eine gescannte URL, eine Seriennummer oder ein Tracking-Code. Die Contracts kodieren Bytes. Sie interpretieren sie nicht. Ein QR Code, der eine bösartige URL kodiert, ist ein gültiger QR Code; die Bewertung der Vertrauenswürdigkeit der Payload liegt daher beim Konsumenten, nicht beim Encoder. Begrenzen Sie die Payload-Länge vor der Kodierung, um die Matrixgröße zu beschränken und einen Denial-of-Service durch ein übergroßes Symbol zu vermeiden. Der GS1-Parser weist fehlerhafte Application Identifiers ab und entfernt damit eine Injektionsfläche. Er prüft den semantischen Inhalt gültiger Felder nicht. Behandeln Sie dekodierte Barcode-Daten überall dort als nicht vertrauenswürdige Eingabe, wo sie wieder in die Anwendung gelangen.

AussageStandardReferenz
QR-Code-Symbole folgen der Spezifikation der QR-Code-Matrix-Symbologie.ISO/IEC 18004QR-Code-Symbologie
Data-Matrix-Symbole folgen der Spezifikation der Data-Matrix-Symbologie.ISO/IEC 16022Data-Matrix-Symbologie
Code-128-Symbole folgen der Spezifikation der linearen Code-128-Symbologie.ISO/IEC 15417Code-128-Symbologie
GS1-Element-Strings werden gemäß der GS1-Application-Identifier-Grammatik geparst.GS1 General SpecificationsApplication Identifiers

Diese Standards werden nach Nummer und Klausel referenziert. Sie sind nicht im verifizierbaren Zitationskorpus vorhanden; daher wird keine reference_id erfasst. Die Engine gibt die Anforderung sinngemäß wieder und zitiert die Quelle. Ziehen Sie die veröffentlichten Standards für maßgebliche Kodierungsregeln heran.

Core definiert und stabilisiert die Encoder-Contracts und liefert die gängigen Symbologien. Die Pro- und Enterprise-Editionen registrieren einen erweiterten Encoder-Satz für zusätzliche Barcode-Symbologien gegen dasselbe BarcodeEncoderInterface, sodass ein kommerzielles Deployment Symbologieabdeckung ohne API-Änderung gewinnt. Core löst registrierte Encoder über BarcodeEncoderRegistry auf. Die Contract-Oberfläche ist über alle Editionen hinweg identisch.