Ir al contenido

Contratos / Código de barras

El dominio de código de barras contiene cuatro contratos: un codificador 1D, un codificador 2D, un codificador genérico detectable por registro y un analizador de datos GS1. Definen la forma que debe cumplir un codificador. Las implementaciones de simbología se registran contra esos contratos.

Ventana de terminal
composer require nextpdf/core:^3

Un codificador de código de barras convierte una cadena de carga útil en una matriz de módulos que el escritor de PDF dibuja. NextPDF separa el contrato por dimensionalidad. Barcode1DEncoderInterface codifica simbologías lineales —Code 128, EAN-13 y similares— y devuelve un objeto de valor BarcodeData. Barcode2DEncoderInterface codifica simbologías matriciales —QR Code, Data Matrix—. Devuelve un objeto de valor Barcode2DData con un mapa de opciones para parámetros específicos de la simbología, como el nivel de corrección de errores.

BarcodeEncoderInterface es el contrato genérico para proveedores de servicios. Cualquier codificador 2D detectable mediante BarcodeEncoderRegistry lo implementa. El contrato devuelve una matriz monocromática Barcode2DData o bien una matriz a color BarcodeColorData, de modo que un codificador registrado puede producir un símbolo a color sin una interfaz aparte. Se espera que los codificadores sean sin estado más allá de la configuración de construcción. El registro entrega una sola instancia compartida por cada tipo registrado, por lo que cualquier estado por llamada sería un defecto.

Gs1DataParserInterface es el contrato de datos estructurados. Analiza una cadena de elementos GS1 y la convierte en un objeto tipado; después vuelve a codificar ese objeto para un portador QR Code, Data Matrix o Code 128. Esto separa la gramática GS1 de la simbología. El analizador valida los identificadores de aplicación una sola vez. Los métodos específicos de cada portador formatean la misma estructura analizada para cada destino. Los cuatro contratos son stable. BarcodeEncoderInterface es estable desde la versión 3.0.0; los demás, desde la 1.0.0. Los métodos nuevos se incorporan únicamente con implementaciones predeterminadas.

TipoClaseMiembros claveEstabilidadDesde
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

En los contratos 2D, el array $options es específico de la simbología (por ejemplo, un nivel de corrección de errores para QR Code). El contrato no restringe sus claves. Cada codificador registrado documenta su propio conjunto de opciones.

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() y write2DBarcode() resuelven un codificador mediante el registro. El código de aplicación rara vez interactúa directamente con los contratos. Basta con indicar una simbología para que el registro suministre el codificador.

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

El servicio depende de los contratos del analizador y del codificador. El bloque catch registra el error y vuelve a lanzar la BarcodeException específica, nunca una \Exception genérica.

  • Un codificador registrado es compartido. Almacenar estado por llamada en un codificador corrompe los renderizados concurrentes. Mantener los codificadores sin estado más allá de la configuración del constructor.
  • BarcodeEncoderInterface::encode() puede devolver datos a color o monocromáticos. El código consumidor debe gestionar tanto Barcode2DData como BarcodeColorData, sin asumir que sean monocromáticos.
  • El array $options 2D no es validado por el contrato. La mayoría de los codificadores ignora silenciosamente una clave desconocida. Verificar el nombre de la clave en la documentación del propio codificador.
  • El análisis GS1 aplica la gramática de forma estricta. Una cadena de elementos con un identificador de aplicación desconocido lanza una BarcodeException en lugar de producir un análisis parcial. Validar la entrada de origen.
  • Los contratos 1D y 2D no son intercambiables. Una carga útil QR pasada a un codificador 1D produce un símbolo no válido. El registro enruta por tipo de simbología, así que conviene preferir el registro antes que una llamada directa al contrato.

El costo de codificación escala con la longitud de la carga útil y el tamaño de la matriz de destino, no con el contrato. Una carga útil Code 128 corta se codifica en microsegundos. Un QR Code denso con corrección de errores alta es el caso 2D más pesado. Aun así, queda holgadamente dentro del performance_budget de 1500 ms de reloj y 64 MB de pico para la página de ejemplo multisímbolo. La matriz se calcula una sola vez y se dibuja como operadores de PDF. La reproducibilidad es bitwise porque la misma carga útil y las mismas opciones siempre producen la misma matriz de módulos. La búsqueda en el registro es O(1). El trabajo recae en el algoritmo de la simbología.

Las cargas útiles de código de barras suelen estar influidas por un atacante: una URL escaneada, un número de serie, un código de seguimiento. Los contratos codifican bytes. No los interpretan. Un QR Code que codifica una URL hostil es un QR Code válido, así que la confianza en la carga útil es responsabilidad del consumidor, no del codificador. Restringir la longitud de la carga útil antes de codificar permite acotar el tamaño de la matriz y evitar una denegación de servicio mediante un símbolo de tamaño excesivo. El analizador GS1 rechaza los identificadores de aplicación malformados, lo que elimina una superficie de inyección. No examina el contenido semántico de los campos válidos. Tratar los datos de código de barras decodificados como entrada no confiable allí donde vuelvan a entrar en la aplicación.

AfirmaciónEstándarReferencia
Los símbolos QR Code siguen la especificación de simbología matricial QR Code.ISO/IEC 18004Simbología QR Code
Los símbolos Data Matrix siguen la especificación de simbología Data Matrix.ISO/IEC 16022Simbología Data Matrix
Los símbolos Code 128 siguen la especificación de simbología lineal Code 128.ISO/IEC 15417Simbología Code 128
Las cadenas de elementos GS1 se analizan según la gramática de identificadores de aplicación GS1.Especificaciones generales GS1Identificadores de aplicación

Estos estándares se citan por número y cláusula. No están presentes en el corpus verificable de citas, por lo que no se registra ningún reference_id. El motor parafrasea el requisito y cita la fuente. Consultar los estándares publicados para conocer las reglas de codificación autoritativas.

El core define y fija los contratos de codificador y proporciona las simbologías comunes. Las ediciones Pro y Enterprise registran un conjunto ampliado de codificadores para simbologías de código de barras adicionales contra la misma BarcodeEncoderInterface, de modo que un despliegue comercial obtiene cobertura de simbologías sin un cambio de API. El core resuelve los codificadores registrados mediante BarcodeEncoderRegistry. La superficie del contrato es idéntica en todas las ediciones.