Support: utilidades compartidas + Clock + Sleeper
De un vistazo
Sección titulada «De un vistazo»El módulo Support contiene las utilidades transversales que el motor usa internamente. También expone una pequeña superficie pública: el reloj de sistema PSR-20, la canalización de recopilación de advertencias y las primitivas de serialización de PDF. La mayor parte del espacio de nombres es infraestructura interna. Esta página documenta las partes en las que puede apoyarse el código externo y señala cuáles son de uso exclusivamente interno.
Instalación
Sección titulada «Instalación»composer require nextpdf/core:^3Vista general conceptual
Sección titulada «Vista general conceptual»Reloj (PSR-20). SystemClock implementa Psr\Clock\ClockInterface. Su now() devuelve la hora actual como un DateTimeImmutable. El modelo PSR-20 define una interfaz de reloj con una sola operación de lectura. Esa operación devuelve la hora actual como un valor de fecha y hora inmutable (PSR-20 psr_20_clock#2.1). SystemClock es el valor predeterminado. El motor lo usa cuando no se inyecta ningún reloj. Para fijar la hora en pruebas, se debe inyectar en su lugar un reloj congelado. Este debe implementar la misma interfaz. Combinar el reloj con Config::deterministic permite obtener una salida idéntica byte a byte.
Canalización de advertencias. WarningCollector es el transporte principal en memoria para los problemas de renderizado no fatales. El motor añade un Warning por cada degradación determinista. Algunos ejemplos son una columna de tabla comprimida, una fuente sin resolver o un glifo ausente. El código llamador las lee después de la generación a través de Document::getWarnings(). Un Warning es un objeto de valor inmutable. Lleva un WarningCode, una WarningSeverity (warning o degraded), la página, el tipo de elemento, el id de la función, un indicador de paridad degradada, un mensaje, un DegradationImpact y un id de capacidad opcional. WarningCode es un enum respaldado por strings con identificadores estables. Llevan el prefijo NEXTPDF_W_ (por ejemplo NEXTPDF_W_FONT_UNRESOLVED). El prefijo permite compararlos con seguridad en las pruebas. addWithPolicy() aplica la DegradationPolicy activa. Bajo una política estricta, un impacto de cumplimiento, semántico o de bloqueo lanza DegradedException. Bajo una política equilibrada, solo un impacto de bloqueo lanza. Una política permisiva nunca lanza excepciones.
Primitivas de PDF. PdfStringEscaper es la única fuente de verdad para el escapado de strings y nombres de PDF. escapeLiteral() escapa los caracteres que exige un string literal de PDF (barra invertida, paréntesis, CR, LF, HT, BS, FF) y elimina NUL. escapeName() codifica en hexadecimal los bytes fuera del ASCII imprimible y del conjunto de delimitadores de PDF para un objeto de nombre. BinaryBuffer es un acumulador binario optimizado para escritura. Construye objetos y streams de PDF. Su modo de streaming vuelca a un manejador php://temp para documentos grandes. También admite las operaciones de rango de bytes que necesita la incrustación de firmas. PdfOperators contiene los strings de formato de los operadores de stream de contenido (trazado, texto, estado gráfico, fuente). Las capas de dibujo y de análisis los comparten.
BinaryBuffer, PdfOperators y la mayor parte del resto de NextPDF\Support\ son infraestructura interna. Las capas de escritura y de dibujo los consumen. Se documentan aquí por exhaustividad y para facilitar la auditoría. No forman parte de la superficie de API pública con soporte. En su lugar, conviene apoyarse en la fachada Document y en el espacio de nombres Contracts. SystemClock, WarningCollector, Warning, WarningCode, WarningSeverity y DegradationImpact son los miembros expuestos al público.
Superficie de la API
Sección titulada «Superficie de la API»| Símbolo | Tipo | Visibilidad | Miembros clave |
|---|---|---|---|
NextPDF\Support\SystemClock | clase final | pública | now(): DateTimeImmutable (PSR-20 ClockInterface) |
NextPDF\Support\WarningCollector | clase final | pública | add(), emit(), addWithPolicy(), getWarnings(), hasWarnings(), hasDegradedParity(), clear() |
NextPDF\Support\Warning | clase final de solo lectura | pública | $code, $severity, $page, $elementType, $featureId, $degradedParity, $message, $impact, $capabilityId |
NextPDF\Support\WarningCode | enum de string | pública | identificadores NEXTPDF_W_* estables |
NextPDF\Support\WarningSeverity | enum de string | pública | Warning, Degraded |
NextPDF\Support\DegradationImpact | enum de string | pública | Cosmetic, LayoutRisk, SemanticLoss, ComplianceRisk, Blocking |
NextPDF\Support\PdfStringEscaper | clase final de solo lectura | interna | escapeLiteral(), escapeName() (estáticos) |
NextPDF\Support\BinaryBuffer | clase final | interna | write(), writeStream(), replaceAt(), extract(), enableStreaming(), getContents() |
NextPDF\Support\PdfOperators | clase final | interna | constantes de strings de formato de operadores de stream de contenido |
Ejemplo de código — Inicio rápido
Sección titulada «Ejemplo de código — Inicio rápido»Leer las advertencias recopiladas después de la generación.
<?php
declare(strict_types=1);
use NextPDF\Support\WarningCollector;
$collector = new WarningCollector();
// The engine appends warnings during rendering. After generation:if ($collector->hasWarnings()) { foreach ($collector->getWarnings() as $warning) { \printf( "[%s] page %d: %s\n", $warning->code->value, $warning->page, $warning->message, ); }}Ejemplo de código — Producción
Sección titulada «Ejemplo de código — Producción»Inyectar un reloj para obtener una hora determinista e interpretar una advertencia de paridad degradada como un fallo de compilación.
<?php
declare(strict_types=1);
use NextPDF\Support\SystemClock;use NextPDF\Support\WarningCollector;use Psr\Clock\ClockInterface;
// Production uses the real system clock.$clock = new SystemClock();$now = $clock->now(); // DateTimeImmutable$epoch = $now->getTimestamp(); // int
// In tests, swap in any ClockInterface that returns a fixed instant// (the parameter is typed to the PSR-20 interface, not SystemClock).function buildReport(ClockInterface $clock): \DateTimeImmutable{ return $clock->now();}
$collector = new WarningCollector();// ... run generation ...if ($collector->hasDegradedParity()) { throw new \RuntimeException('Output parity degraded; failing the build.');}Casos límite y trampas
Sección titulada «Casos límite y trampas»SystemClock::now()devuelve un nuevoDateTimeImmutableen cada llamada. No asumir que dos llamadas devuelven el mismo instante. Para una hora fija, inyectar un reloj congelado.WarningCollectorestá en memoria y es por instancia. Es el canal principal. El sidecar JSON y el STDERR de la CLI se emiten en el límite de salida, no por el propio recolector.addWithPolicy()puede lanzarDegradedExceptiona mitad del renderizado bajo una política estricta. Capturarla en el límite de generación si se necesita una salida parcial.WarningCodeexpone valores que son strings estables: comparar por el caso del enum, no por el texto del mensaje, que es legible por humanos y puede cambiar.BinaryBuffer::getLength()es un alias intencional degetOffset()por paridad con la interfaz de stream. Ambos devuelven el mismo recuento de bytes.- Tratar
PdfStringEscaper,BinaryBufferyPdfOperatorscomo internos. No están cubiertos por la promesa de estabilidad de la API pública.
Rendimiento
Sección titulada «Rendimiento»SystemClock::now() es una única construcción de objeto, O(1). Los añadidos de WarningCollector son inserciones en lista O(1) amortizadas. getWarnings() devuelve la lista subyacente. BinaryBuffer en modo de streaming limita la memoria a su umbral maxmemory (predeterminado 2 MB) antes de volcar al disco, lo que mantiene plano el pico de memoria para documentos grandes. El performance_budget predeterminado para esta página de referencia es wall_ms: 1500, peak_mb: 64.
Notas de seguridad
Sección titulada «Notas de seguridad»La superficie del reloj permite eliminar el indeterminismo del reloj de pared de la salida firmada y con marca de tiempo al inyectar un reloj fijo junto con Config::deterministic. PdfStringEscaper es el único escapador auditable para la salida de strings y nombres de PDF. Enrutar toda la emisión de strings a través de él evita la inyección de contenido mediante paréntesis o delimitadores sin escapar en texto proporcionado por el usuario. Las advertencias pueden llevar detalles derivados del documento (tipos de elemento, ids de función). Sanear la salida de advertencias antes de reenviarla a un destino de logs de baja confianza.
Conformidad
Sección titulada «Conformidad»| Especificación | Cláusula | Tema |
|---|---|---|
| PSR-20 (PHP-FIG) | psr_20_clock#2.1 | La operación de lectura del reloj devuelve una fecha y hora inmutable |
| ISO 32000-2:2020 | §7.3.4.2 / §7.3.5 | Escapado de strings literales y de objetos de nombre (parafraseado; texto de la norma ISO no citado, sin chunk fijado) |
SystemClock implementa la ClockInterface de PSR-20. El escapador sigue las reglas de caracteres de strings literales y de objetos de nombre de PDF. El texto de la norma ISO se parafrasea según la política de citas del sitio y no se fija ningún chunk literal.
Véase también
Sección titulada «Véase también»/modules/core/exception/—DegradedExceptionlanzada poraddWithPolicy()/modules/core/contracts/—DegradationPolicy,Capability/modules/core/observability/— reenvío de advertencias y métricas/modules/core/config/—Config::deterministicse combina con el reloj/modules/core/writer/— consumidor interno deBinaryBufferyPdfOperators
Glosario: PSR-20 · política de degradación · objeto de valor