Przejdź do głównej zawartości

Support: wspólne narzędzia + Clock + Sleeper

Moduł Support zawiera wspólne narzędzia używane wewnętrznie przez silnik. Udostępnia też niewielką powierzchnię publiczną: zegar systemowy zgodny z PHP Standards Recommendation 20 (PSR-20), potok zbierania ostrzeżeń oraz prymitywy serializacji formatu Portable Document Format (PDF). Większość tej przestrzeni nazw stanowi infrastruktura wewnętrzna. Ta strona dokumentuje elementy, na których można polegać, i oznacza elementy przeznaczone wyłącznie do użytku wewnętrznego.

Okno terminala
composer require nextpdf/core:^3

Zegar (PSR-20). SystemClock implementuje Psr\Clock\ClockInterface. Metoda now() zwraca bieżący czas jako DateTimeImmutable. Model PSR-20 definiuje interfejs zegara z jedną operacją odczytu, która zwraca bieżący czas jako niezmienną wartość daty i czasu (PSR-20 psr_20_clock#2.1). SystemClock jest domyślnym zegarem; silnik używa go, gdy nie wstrzyknięto własnego zegara. Aby uzyskać stały czas w testach, wstrzyknij zamrożony zegar implementujący ten sam interfejs. Połącz zegar z Config::deterministic, gdy potrzebny jest wynik identyczny bajtowo.

Potok ostrzeżeń. WarningCollector jest głównym mechanizmem przekazywania w pamięci dla niekrytycznych problemów renderowania. Silnik dodaje Warning dla każdej deterministycznej degradacji, takiej jak zwężona kolumna tabeli, nierozwiązana czcionka lub brakujący glif. Po wygenerowaniu dokumentu ostrzeżenia odczytuje się przez Document::getWarnings(). Warning jest niezmiennym obiektem wartości. Zawiera WarningCode, WarningSeverity (warning lub degraded), numer strony, typ elementu, identyfikator funkcji, flagę degradacji parzystości, komunikat, DegradationImpact oraz opcjonalny identyfikator możliwości. WarningCode jest wyliczeniem typu string ze stabilnymi identyfikatorami. Identyfikatory mają przedrostek NEXTPDF_W_, na przykład NEXTPDF_W_FONT_UNRESOLVED, dzięki czemu można je bezpiecznie dopasowywać w testach. addWithPolicy() wymusza aktywną DegradationPolicy. Przy zasadzie strict skutek związany ze zgodnością, semantyką albo blokujący powoduje zgłoszenie DegradedException. Przy zasadzie balanced zgłaszany jest tylko skutek blokujący. Przy zasadzie permissive wyjątek nigdy nie jest zgłaszany.

Prymitywy PDF. PdfStringEscaper jest jedynym źródłem prawdy dla zmiany znaczenia łańcuchów i nazw PDF. escapeLiteral() zmienia znaczenie znaków wymaganych w dosłownym łańcuchu PDF: ukośnika wstecznego, nawiasów, powrotu karetki (CR), wysuwu wiersza (LF), tabulacji poziomej (HT), backspace (BS) i wysuwu strony (FF). Usuwa też bajt NUL. escapeName() koduje szesnastkowo bajty spoza drukowalnego zakresu American Standard Code for Information Interchange (ASCII) oraz bajty należące do zestawu ograniczników PDF dla obiektu nazwy. BinaryBuffer jest binarnym akumulatorem zoptymalizowanym pod kątem zapisu obiektów i strumieni PDF. W trybie strumieniowym dla dużych dokumentów przenosi dane do uchwytu php://temp. Obsługuje też operacje na zakresach bajtów wymagane przy osadzaniu podpisu. PdfOperators przechowuje łańcuchy formatujące dla operatorów strumienia treści dla ścieżek, tekstu, stanu grafiki i czcionek. Warstwy rysowania i parsera współdzielą te łańcuchy.

BinaryBuffer, PdfOperators i większość pozostałej części NextPDF\Support\ to infrastruktura wewnętrzna. Korzystają z nich warstwy zapisu i rysowania. Ta strona dokumentuje je ze względu na kompletność i audyt. Nie należą do obsługiwanego publicznego interfejsu programowania aplikacji (API). W ich miejsce używaj fasady Document oraz przestrzeni nazw Contracts. SystemClock, WarningCollector, Warning, WarningCode, WarningSeverity i DegradationImpact to składowe publiczne.

SymbolRodzajWidocznośćKluczowe składowe
NextPDF\Support\SystemClockklasa finalpublicnow(): DateTimeImmutable (PSR-20 ClockInterface)
NextPDF\Support\WarningCollectorklasa finalpublicadd(), emit(), addWithPolicy(), getWarnings(), hasWarnings(), hasDegradedParity(), clear()
NextPDF\Support\Warningklasa final readonlypublic$code, $severity, $page, $elementType, $featureId, $degradedParity, $message, $impact, $capabilityId
NextPDF\Support\WarningCodewyliczenie typu stringpublicstabilne identyfikatory NEXTPDF_W_*
NextPDF\Support\WarningSeveritywyliczenie typu stringpublicWarning, Degraded
NextPDF\Support\DegradationImpactwyliczenie typu stringpublicCosmetic, LayoutRisk, SemanticLoss, ComplianceRisk, Blocking
NextPDF\Support\PdfStringEscaperklasa final readonlyinternalescapeLiteral(), escapeName() (statyczne)
NextPDF\Support\BinaryBufferklasa finalinternalwrite(), writeStream(), replaceAt(), extract(), enableStreaming(), getContents()
NextPDF\Support\PdfOperatorsklasa finalinternalstałe łańcuchów formatu operatorów strumienia treści

Odczytaj zebrane ostrzeżenia po wygenerowaniu.

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

Wstrzyknij zegar, aby czas był deterministyczny, i traktuj ostrzeżenie o degradacji parzystości jako niepowodzenie kompilacji.

<?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() zwraca nowy DateTimeImmutable przy każdym wywołaniu. Nie zakładaj, że dwa wywołania zwrócą ten sam moment. Aby uzyskać stały czas, wstrzyknij zamrożony zegar.
  • WarningCollector działa w pamięci i jest powiązany z instancją. To podstawowy kanał ostrzeżeń. Plik towarzyszący JavaScript Object Notation (JSON) oraz standardowe wyjście błędów (STDERR) interfejsu wiersza poleceń (CLI) są emitowane na granicy wyjścia, a nie przez sam kolektor.
  • addWithPolicy() może zgłosić DegradedException w trakcie renderowania przy zasadzie strict. Przechwytuj wyjątek na granicy generowania, jeśli potrzebny jest częściowy wynik.
  • Wartości WarningCode są stabilnymi łańcuchami. Dopasowuj do wariantu wyliczenia, a nie do czytelnego dla człowieka tekstu komunikatu, który może się zmienić.
  • BinaryBuffer::getLength() jest celowym aliasem getOffset() dla zgodności z interfejsem strumienia. Oba zwracają tę samą liczbę bajtów.
  • Traktuj PdfStringEscaper, BinaryBuffer i PdfOperators jako infrastrukturę wewnętrzną. Nie są objęte obietnicą stabilności publicznego API.

SystemClock::now() tworzy jeden obiekt i działa w czasie O(1). Dodawanie wpisów do WarningCollector to zamortyzowane operacje dodania do listy w czasie O(1). getWarnings() zwraca listę bazową. W trybie strumieniowym BinaryBuffer przechowuje dane w pamięci do progu maxmemory (domyślnie 2 MB), zanim przeniesie je na dysk, co utrzymuje stały poziom szczytowego zużycia pamięci dla dużych dokumentów. Domyślny performance_budget dla tej strony referencyjnej to wall_ms: 1500, peak_mb: 64.

Użyj powierzchni zegara, aby usunąć niedeterminizm zegara ściennego z podpisanego i oznaczonego znacznikiem czasu wyniku, wstrzykując stały zegar wraz z Config::deterministic. PdfStringEscaper jest jedynym audytowalnym mechanizmem zmiany znaczenia dla łańcuchów i nazw PDF. Kieruj przez niego całą emisję łańcuchów, aby zapobiec wstrzyknięciu treści przez niezabezpieczone nawiasy lub ograniczniki w tekście dostarczonym przez użytkownika. Ostrzeżenia mogą zawierać szczegóły pochodzące z dokumentu, takie jak typy elementów i identyfikatory funkcji. Oczyść wyjście ostrzeżeń, zanim przekażesz je do ujścia dziennika o niskim poziomie zaufania.

SpecyfikacjaKlauzulaTemat
PSR-20 (PHP-FIG)psr_20_clock#2.1Operacja odczytu zegara zwraca niezmienną wartość daty i czasu
ISO 32000-2:2020§7.3.4.2 / §7.3.5Zmiana znaczenia łańcuchów dosłownych i obiektów nazw (parafraza; tekst ISO nie jest cytowany, brak przypiętego fragmentu)

SystemClock implementuje ClockInterface z PSR-20. Mechanizm zmiany znaczenia obejmuje reguły znaków dla łańcuchów dosłownych i obiektów nazw PDF. Tekst ISO jest parafrazowany zgodnie z zasadami cytowania witryny; nie przypięto żadnego dosłownego fragmentu.

  • /modules/core/exception/DegradedException zgłaszany przez addWithPolicy()
  • /modules/core/contracts/DegradationPolicy, Capability
  • /modules/core/observability/ — przekazywanie ostrzeżeń i metryki
  • /modules/core/config/Config::deterministic współdziała z zegarem
  • /modules/core/writer/ — wewnętrzny odbiorca BinaryBuffer i PdfOperators

Słownik: PSR-20 · zasada degradacji · obiekt wartości