Zum Inhalt springen

Support: gemeinsame Utilities + Clock + Sleeper

Das Support-Modul enthält modulübergreifende Utilities, die die Engine intern nutzt. Darüber hinaus stellt es eine kleine öffentliche API-Oberfläche bereit: die PSR-20-Systemuhr, die Pipeline zur Warnungssammlung und die Primitive für die PDF-Serialisierung. Der Großteil des Namespace ist interne Infrastruktur. Diese Seite dokumentiert die Teile, auf die sich externe Aufrufer verlassen dürfen, und kennzeichnet die rein internen.

Terminal-Fenster
composer require nextpdf/core:^3

Clock (PSR-20). SystemClock implementiert Psr\Clock\ClockInterface. Die Methode now() liefert die aktuelle Zeit als DateTimeImmutable. Das PSR-20-Modell definiert ein Clock-Interface mit einer einzigen Leseoperation. Diese Operation liefert die aktuelle Zeit als unveränderlichen Datums-Zeit-Wert (PSR-20 psr_20_clock#2.1). SystemClock ist der Standard. Die Engine nutzt sie, wenn keine Clock injiziert wird. Für eine feste Zeit in Tests injizieren Sie stattdessen eine eingefrorene Clock. Sie muss dasselbe Interface implementieren. Kombinieren Sie die Clock mit Config::deterministic, um eine bytegenau identische Ausgabe zu erhalten.

Warnungs-Pipeline. WarningCollector ist der zentrale In-Memory-Transport für nicht fatale Rendering-Probleme. Die Engine hängt bei jeder deterministischen Degradierung eine Warning an. Beispiele sind eine gestauchte Tabellenspalte, eine nicht aufgelöste Schrift oder eine fehlende Glyphe. Der Aufrufer liest die Warnungen nach der Generierung über Document::getWarnings(). Eine Warning ist ein unveränderliches Wertobjekt. Sie enthält einen WarningCode, eine WarningSeverity (warning oder degraded), die Seite, den Elementtyp, die Feature-ID, ein Degraded-Parity-Flag, eine Nachricht, einen DegradationImpact und eine optionale Capability-ID. WarningCode ist ein String-basiertes Enum stabiler Bezeichner. Die Werte tragen das Präfix NEXTPDF_W_ (zum Beispiel NEXTPDF_W_FONT_UNRESOLVED). Durch das Präfix lassen sie sich in Tests zuverlässig abgleichen. addWithPolicy() erzwingt die aktive DegradationPolicy. Unter einer strikten Policy löst ein Impact mit Compliance-, Semantik- oder blockierendem Charakter eine DegradedException aus. Unter einer ausgewogenen Policy löst nur ein Impact mit blockierendem Charakter eine DegradedException aus. Eine permissive Policy löst nie eine DegradedException aus.

PDF-Primitive. PdfStringEscaper ist die maßgebliche Stelle für das Escaping von PDF-Strings und -Namen. escapeLiteral() maskiert die Zeichen, die ein PDF-Literal-String erfordert (Reverse Solidus, Klammern, CR, LF, HT, BS, FF), und entfernt NUL. escapeName() kodiert für ein Name-Objekt die Bytes außerhalb des druckbaren ASCII und der Menge der PDF-Trennzeichen als Hex. BinaryBuffer ist ein für Schreibzugriffe optimierter Binärakkumulator. Er baut PDF-Objekte und -Streams auf. Sein Streaming-Modus lagert bei großen Dokumenten in ein php://temp-Handle aus. Er unterstützt außerdem die Byte-Range-Operationen, die zum Einbetten von Signaturen erforderlich sind. PdfOperators enthält die Format-Strings der Content-Stream-Operatoren (Path, Text, Graphics-State, Font). Drawing- und Parser-Schichten verwenden sie gemeinsam.

BinaryBuffer, PdfOperators und der größte Teil des restlichen NextPDF\Support\ sind interne Infrastruktur. Die Writer- und Drawing-Schichten konsumieren sie. Sie sind hier der Vollständigkeit und der Auditierbarkeit halber dokumentiert. Sie gehören nicht zur unterstützten öffentlichen API-Oberfläche. Verlassen Sie sich stattdessen auf die Document-Fassade und den Contracts-Namespace. SystemClock, WarningCollector, Warning, WarningCode, WarningSeverity und DegradationImpact sind die öffentlichen Member.

SymbolArtSichtbarkeitWichtige Member
NextPDF\Support\SystemClockfinal classpublicnow(): DateTimeImmutable (PSR-20 ClockInterface)
NextPDF\Support\WarningCollectorfinal classpublicadd(), emit(), addWithPolicy(), getWarnings(), hasWarnings(), hasDegradedParity(), clear()
NextPDF\Support\Warningfinal readonly classpublic$code, $severity, $page, $elementType, $featureId, $degradedParity, $message, $impact, $capabilityId
NextPDF\Support\WarningCodeString-Enumpublicstabile NEXTPDF_W_*-Bezeichner
NextPDF\Support\WarningSeverityString-EnumpublicWarning, Degraded
NextPDF\Support\DegradationImpactString-EnumpublicCosmetic, LayoutRisk, SemanticLoss, ComplianceRisk, Blocking
NextPDF\Support\PdfStringEscaperfinal readonly classinternescapeLiteral(), escapeName() (statisch)
NextPDF\Support\BinaryBufferfinal classinternwrite(), writeStream(), replaceAt(), extract(), enableStreaming(), getContents()
NextPDF\Support\PdfOperatorsfinal classinternFormat-String-Konstanten für Content-Stream-Operatoren

Gesammelte Warnungen nach der Generierung auslesen.

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

Injizieren Sie eine Clock für deterministische Zeit und behandeln Sie eine Degraded-Parity-Warnung als Build-Fehler.

<?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() liefert bei jedem Aufruf ein neues DateTimeImmutable. Gehen Sie nicht davon aus, dass zwei Aufrufe denselben Zeitpunkt liefern. Für eine feste Zeit injizieren Sie eine eingefrorene Clock.
  • WarningCollector lebt im Arbeitsspeicher und ist an eine Instanz gebunden. Er ist der primäre Kanal. Das JSON-Sidecar und CLI-STDERR werden erst an der Ausgabegrenze ausgegeben, nicht vom Collector selbst.
  • addWithPolicy() kann unter einer strikten Policy mitten im Rendern eine DegradedException werfen. Fangen Sie sie an der Generierungsgrenze ab, wenn Sie eine teilweise Ausgabe wünschen.
  • WarningCode-Werte sind stabile Strings — gleichen Sie den Enum-Case ab, nicht den Nachrichtentext, der menschenlesbar ist und sich ändern kann.
  • BinaryBuffer::getLength() ist ein bewusster Alias von getOffset() für die Parität mit der Stream-Schnittstelle. Beide liefern dieselbe Byte-Anzahl.
  • Behandeln Sie PdfStringEscaper, BinaryBuffer und PdfOperators als intern. Sie sind nicht durch das Stabilitätsversprechen der öffentlichen API abgedeckt.

SystemClock::now() ist eine einzelne Objektkonstruktion, O(1). WarningCollector-Anhängevorgänge sind als Push-Operationen auf eine Liste amortisiert O(1). getWarnings() liefert die zugrunde liegende Liste. BinaryBuffer begrenzt im Streaming-Modus den Speicher auf seinen maxmemory-Schwellenwert (Standard 2 MB), bevor er auf die Festplatte auslagert; dadurch bleibt der Spitzenspeicher für große Dokumente niedrig. Das standardmäßige performance_budget für diese Referenzseite ist wall_ms: 1500, peak_mb: 64.

Die Clock-Schnittstelle ermöglicht es Ihnen, den Nichtdeterminismus der Wall-Clock aus signierter und mit Zeitstempel versehener Ausgabe zu entfernen, indem Sie eine feste Clock zusammen mit Config::deterministic injizieren. PdfStringEscaper ist der einzige auditierbare Escaper für die Ausgabe von PDF-Strings und -Namen. Sämtliche String-Ausgabe über ihn zu führen verhindert Content-Injection durch nicht maskierte Klammern oder Trennzeichen in von Nutzern gelieferten Texten. Warnungen können dokumentbezogene Details enthalten (Elementtypen, Feature-IDs). Bereinigen Sie die Warnungsausgabe, bevor Sie sie an einen wenig vertrauenswürdigen Log-Sink weiterleiten.

SpezifikationAbschnittThema
PSR-20 (PHP-FIG)psr_20_clock#2.1Clock-Leseoperation liefert einen unveränderlichen Datum-Zeit-Wert
ISO 32000-2:2020§7.3.4.2 / §7.3.5Escaping von Literal-Strings und Name-Objekten (paraphrasiert; ISO-Text nicht zitiert, kein Chunk gepinnt)

SystemClock implementiert das PSR-20 ClockInterface. Der Escaper folgt den PDF-Zeichenregeln für Literal-Strings und Name-Objekte. Der ISO-Text ist gemäß der Zitationsrichtlinie der Website paraphrasiert; es ist kein wörtlicher Chunk gepinnt.

  • /modules/core/exception/DegradedException, ausgelöst von addWithPolicy()
  • /modules/core/contracts/DegradationPolicy, Capability
  • /modules/core/observability/ — Warnungsweiterleitung und Metriken
  • /modules/core/config/Config::deterministic ist das Gegenstück zur Clock
  • /modules/core/writer/ — interner Konsument von BinaryBuffer und PdfOperators

Glossar: PSR-20 · Degradierungs-Policy · Wertobjekt