Aller au contenu

Support : utilitaires partagés + Clock + Sleeper

Le module Support regroupe les utilitaires transversaux utilisés en interne par le moteur. Il expose aussi une petite surface publique : l’horloge système PSR-20, le pipeline de collecte des avertissements et les primitives de sérialisation PDF. L’essentiel de l’espace de noms relève de l’infrastructure interne. Cette page documente les éléments sur lesquels un appelant externe peut s’appuyer, et signale ceux réservés à l’usage interne.

Fenêtre de terminal
composer require nextpdf/core:^3

Horloge (PSR-20). SystemClock implémente Psr\Clock\ClockInterface. Sa méthode now() renvoie l’heure courante sous la forme d’un DateTimeImmutable. Le modèle PSR-20 définit une interface d’horloge limitée à une seule opération de lecture. Cette opération renvoie l’heure courante sous la forme d’une valeur date-heure immuable (PSR-20 psr_20_clock#2.1). SystemClock est l’implémentation par défaut. Le moteur l’utilise quand aucune horloge n’est injectée. Pour figer le temps dans les tests, injecte plutôt une horloge gelée. Elle doit implémenter la même interface. Associe l’horloge à Config::deterministic pour obtenir une sortie strictement identique.

Pipeline d’avertissements. WarningCollector est le principal transport en mémoire des problèmes de rendu non fatals. Le moteur ajoute un Warning à chaque dégradation déterministe : par exemple, une colonne de tableau resserrée, une police non résolue ou un glyphe manquant. L’appelant les lit après la génération via Document::getWarnings(). Un Warning est un objet valeur immuable. Il porte un WarningCode, une WarningSeverity (warning ou degraded), la page, le type d’élément, l’identifiant de fonctionnalité, un indicateur de parité dégradée, un message, un DegradationImpact et un identifiant de capacité optionnel. WarningCode est une énumération adossée à des chaînes d’identifiants stables. Ces identifiants portent le préfixe NEXTPDF_W_ (par exemple NEXTPDF_W_FONT_UNRESOLVED). Ce préfixe les rend fiables pour le filtrage dans les tests. addWithPolicy() applique la DegradationPolicy en vigueur. Sous une politique stricte, un impact lié à la conformité, à la sémantique ou bloquant lève DegradedException. Sous une politique équilibrée, seul un impact bloquant lève une exception. Une politique permissive n’en lève jamais.

Primitives PDF. PdfStringEscaper est la source de vérité unique pour l’échappement des chaînes et des noms PDF. escapeLiteral() échappe les caractères exigés par une chaîne littérale PDF (solidus inverse, parenthèses, CR, LF, HT, BS, FF) et supprime le NUL. escapeName() encode en hexadécimal les octets hors de l’ASCII imprimable et du jeu de délimiteurs PDF pour un objet nom. BinaryBuffer est un accumulateur binaire optimisé pour l’écriture. Il construit les objets et les flux PDF. Le mode streaming bascule vers un descripteur php://temp pour les gros documents. Il prend aussi en charge les opérations sur plage d’octets nécessaires à l’intégration de signature. PdfOperators contient les chaînes de format des opérateurs de flux de contenu (tracé, texte, état graphique, police). Les couches de dessin et d’analyse les partagent.

BinaryBuffer, PdfOperators et la majeure partie du reste de NextPDF\Support\ relèvent de l’infrastructure interne. Les couches d’écriture et de dessin les consomment. Ces éléments sont documentés ici par souci d’exhaustivité et d’audit. Ils ne font pas partie de la surface d’API publique prise en charge. Appuie-toi plutôt sur la façade Document et sur l’espace de noms Contracts. SystemClock, WarningCollector, Warning, WarningCode, WarningSeverity et DegradationImpact sont les membres exposés publiquement.

SymboleNatureVisibilitéMembres clés
NextPDF\Support\SystemClockclasse finalpublicnow(): DateTimeImmutable (PSR-20 ClockInterface)
NextPDF\Support\WarningCollectorclasse finalpublicadd(), emit(), addWithPolicy(), getWarnings(), hasWarnings(), hasDegradedParity(), clear()
NextPDF\Support\Warningclasse final readonlypublic$code, $severity, $page, $elementType, $featureId, $degradedParity, $message, $impact, $capabilityId
NextPDF\Support\WarningCodeénumération de chaînespublicidentifiants NEXTPDF_W_* stables
NextPDF\Support\WarningSeverityénumération de chaînespublicWarning, Degraded
NextPDF\Support\DegradationImpacténumération de chaînespublicCosmetic, LayoutRisk, SemanticLoss, ComplianceRisk, Blocking
NextPDF\Support\PdfStringEscaperclasse final readonlyinterneescapeLiteral(), escapeName() (statiques)
NextPDF\Support\BinaryBufferclasse finalinternewrite(), writeStream(), replaceAt(), extract(), enableStreaming(), getContents()
NextPDF\Support\PdfOperatorsclasse finalinterneconstantes de chaînes de format des opérateurs de flux de contenu

Lis les avertissements collectés après la génération.

<?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,
);
}
}

Injecte une horloge afin de rendre le temps déterministe et traite un avertissement de parité dégradée comme un échec de build.

<?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.');
}
  • SystemClock::now() renvoie un nouveau DateTimeImmutable à chaque appel. Ne suppose pas que deux appels renvoient le même instant. Pour figer le temps, injecte une horloge gelée.
  • WarningCollector est en mémoire et spécifique à chaque instance. C’est le canal principal. Le fichier JSON annexe et le STDERR de la CLI sont émis à la frontière de sortie, et non par le collecteur lui-même.
  • addWithPolicy() peut lever DegradedException pendant le rendu sous une politique stricte. Intercepte-la à la frontière de génération si tu veux une sortie partielle.
  • WarningCode expose des valeurs qui sont des chaînes stables — filtre sur le cas d’énumération, pas sur le texte du message, qui est destiné à être lu par des humains et peut changer.
  • BinaryBuffer::getLength() est un alias intentionnel de getOffset() pour la parité avec l’interface de flux. Les deux renvoient le même nombre d’octets.
  • Traite PdfStringEscaper, BinaryBuffer et PdfOperators comme internes. Ils ne sont pas couverts par la promesse de stabilité de l’API publique.

SystemClock::now() est une simple construction d’objet, en O(1). Les ajouts de WarningCollector sont des ajouts à une liste, amortis en O(1). getWarnings() renvoie la liste sous-jacente. BinaryBuffer en mode streaming limite la mémoire à son seuil maxmemory (2 Mo par défaut) avant de basculer sur disque, ce qui maintient un pic mémoire constant pour les gros documents. Le performance_budget par défaut pour cette page de référence est wall_ms: 1500, peak_mb: 64.

La surface d’horloge te permet d’éliminer le non-déterminisme lié à l’heure système des sorties signées et horodatées en injectant une horloge fixe aux côtés de Config::deterministic. PdfStringEscaper est l’unique échappeur auditable pour les chaînes et noms PDF en sortie. En faisant passer toute l’émission de chaînes par lui, tu empêches l’injection de contenu via des parenthèses ou des délimiteurs non échappés dans le texte fourni par l’utilisateur. Les avertissements peuvent porter des détails dérivés du document (types d’éléments, identifiants de fonctionnalités). Nettoie la sortie des avertissements avant de la transmettre à une destination de journalisation peu fiable.

SpécificationClauseSujet
PSR-20 (PHP-FIG)psr_20_clock#2.1L’opération de lecture de l’horloge renvoie une date-heure immuable
ISO 32000-2:2020§7.3.4.2 / §7.3.5Échappement des chaînes littérales et des objets nom (paraphrasé ; texte ISO non cité, aucun extrait épinglé)

SystemClock implémente la ClockInterface PSR-20. L’échappeur suit les règles de caractères PDF pour les chaînes littérales et les objets nom. Le texte ISO est paraphrasé conformément à la politique de citation du site, et aucun extrait verbatim n’est épinglé.

  • /modules/core/exception/DegradedException levée par addWithPolicy()
  • /modules/core/contracts/DegradationPolicy, Capability
  • /modules/core/observability/ — transmission des avertissements et des métriques
  • /modules/core/config/Config::deterministic s’associe à l’horloge
  • /modules/core/writer/ — consommateur interne de BinaryBuffer et PdfOperators

Glossaire : PSR-20 · politique de dégradation · objet valeur