Model potoku
Spec: ISO 32000-2, §7.5 ISO 32000-2 §7.5 Evidence: Code-backed
W skrócie
Dział zatytułowany „W skrócie”Dokument NextPDF nie powstaje w jednym, nieprzejrzystym kroku. Przechodzi przez niewielką liczbę jawnych etapów: fasadę, która zapisuje intencję, warstwę treści przekształcającą tę intencję w model oraz writer, który serializuje model do zgodnego pliku PDF. Ta strona wyjaśnia ten model i powody, dla których sprawdza się on w silniku.
Dlaczego to ma znaczenie
Dział zatytułowany „Dlaczego to ma znaczenie”Format pliku PDF sam w sobie ma strukturę warstwową — nagłówek, ciało obiektów, tablicę odsyłaczy oraz zwiastun — a writer musi spójnie złożyć te elementy w całość. Jeśli silnik, który tworzy PDF, jest jedną splątaną procedurą, każda zmiana naraża na ryzyko każdy wynik. Jedynym sposobem na uzyskanie pewności jest wtedy renderowanie całych dokumentów i sprawdzanie ich wzrokowo, co jest powolne, późne i mało przekonujące.
Jawny potok odwraca tę zależność. Każdy etap ma jedno zadanie i typowaną granicę, więc zmianę można przeanalizować i przetestować na etapie, którego dotyczy, a nie dopiero na końcu pliku. Architektura jest tu przede wszystkim decyzją o testowalności i rozszerzalności.
Wersja skrócona
Dział zatytułowany „Wersja skrócona”- Publicznym punktem wejścia jest fasada Document. To płynny, jednorazowy konstruktor bezpieczny dla wątków roboczych, który zapisuje to, co ma powstać, a nie jak ma zostać zserializowane.
- Fasada deleguje zadania do około dwóch tuzinów wyspecjalizowanych traitów odpowiedzialności (wyjście tekstu, rysowanie, strony, zabezpieczenia, nawigacja i tak dalej) — każdy z jedną odpowiedzialnością, a nie jedna gigantyczna klasa.
- Treść trafia jedną z dwóch dróg: bezpośrednie rysowanie (prymitywy graficzne) albo silnik HTML/CSS. Obie tworzą ten sam wewnętrzny model dokumentu.
- Dedykowany writer PDF serializuje ten model, wybierając strategię PDF 1.4 / 1.7 / 2.0. Tworzenie poprawnej struktury pliku odbywa się tutaj i nigdzie indziej.
- Stan o długim czasie życia (rejestry czcionek i obrazów) ma zasięg procesu i jest współdzielony; stan na żądanie (dokument) jest tworzony od nowa i nigdy nie jest ponownie używany. Ta granica jest jawna, dzięki czemu środowiska wątków roboczych pozostają bezpieczne.
Jak podchodzi do tego NextPDF
Dział zatytułowany „Jak podchodzi do tego NextPDF”Najprościej zobaczyć ten model, śledząc dokument od wywołania do bajtów.
- Document facade Fluent, use-once builder; records intent via concern traits.
- Content production Direct drawing or the HTML/CSS engine — both build one document model.
- Document model Accumulated pages, content, and resources held as typed state.
- PDF writer Serialises the model; selects a PDF 1.4 / 1.7 / 2.0 strategy.
- Conforming PDF Header, object body, cross-reference table, trailer.
Dwie decyzje projektowe czynią to czymś więcej niż diagramem.
Fasada jest komponowana, a nie monolityczna. Document nie implementuje każdej funkcji samodzielnie; deleguje każdy obszar do dedykowanego traitu odpowiedzialności — wyjście tekstu, rysowanie, strony, zabezpieczenia, typografia, nawigacja, transakcje i tak dalej. Nowa metoda dokumentu należy do traitu, który jest właścicielem danego obszaru, a nie do samej fasady. Klasa, którą wywołujesz, pozostaje niewielka, a odpowiedzialności są rozdzielone.
Writer ma wyłączną odpowiedzialność za strukturę pliku. Produkcja treści decyduje o tym, jakie znaczniki i obiekty istnieją; writer decyduje o tym, jak stają się one poprawnym plikiem PDF oraz która strategia wersji ma zastosowanie. Ten podział egzekwuje reguła architektoniczna: kod układu i treści nie emituje ostatecznej struktury pliku, a writer nie podejmuje decyzji o układzie. Korzyść polega na tym, że pytanie „czy wynik jest poprawnym plikiem PDF?” ma dokładnie jedno miejsce do przetestowania.
Granica czasu życia stanu jest częścią modelu, a nie kwestią dopisaną na końcu. Rejestry czcionek i obrazów żyją przez cały czas działania procesu i są współdzielone między żądaniami; dokument, jego kontekst renderowania oraz writer są tworzone na żądanie i niszczone. W środowisku wątków roboczych to rozróżnienie decyduje o różnicy między bezpiecznym ponownym użyciem a uszkodzeniem stanu między żądaniami. Z tego powodu jest ono określone w architekturze, a nie pozostawione samej dyscyplinie.
Co mówią dowody
Dział zatytułowany „Co mówią dowody”Ta strona jest Evidence: Code-backed . Etapy odwzorowują rzeczywistą strukturę w repozytorium rdzenia:
- Fasada i jej delegacja to
src/Core/Document.phporaz traity odpowiedzialności wsrc/Core/Concerns/(wyjście tekstu, wyjście, rysowanie, strony, zabezpieczenia, typografia, nawigacja, transakcje i więcej — każdy z pojedynczą odpowiedzialnością). - Dwie drogi treści to silnik HTML/CSS (
src/Html/) oraz bezpośrednie rysowanie (src/Graphics/), obie zasilające wewnętrzny model. - Serializacja i strategia wersji PDF znajdują się w
src/Writer/(PdfWriter.php, z jawnymi klasami strategii PDF 1.4 / 1.7 / 2.0). - Granica między czasem życia procesu a żądaniem to projekt bezpieczny dla wątków roboczych, opisany w przeglądzie architektury i zweryfikowany przez dostarczony przykład fabryki wątków roboczych, który współdzieli
FontRegistryorazImageRegistrymiędzy żądaniami, tworząc jednocześnie każdyDocumentod nowa.
Cel wyznacza format. Efektem działania writera musi być nagłówek, ciało obiektów, tablica odsyłaczy oraz zwiastun zgodnie z Spec: ISO 32000-2, §7.5 ISO 32000-2 §7.5 . Skupienie tego obowiązku w jednym etapie pozwala reszcie silnika pozostać skoncentrowaną na treści zamiast na składaniu struktury pliku.
Przykład praktyczny
Dział zatytułowany „Przykład praktyczny”Zadaniem fasady jest sprawić, by intencja pozostała czytelna jako intencja. Droga treści oraz writer pozostają niewidoczne w miejscu wywołania:
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone(); // facade$doc->setTitle('Quarterly Report'); // metadata concern$doc->addPage(); // pages concern$doc->setFont('helvetica', 'B', 16); // typography concern$doc->cell(0, 12, 'Summary', newLine: true); // text-output concern$doc->writeHtml('<p>Generated in-process.</p>'); // HTML content path$doc->save(__DIR__ . '/report.pdf'); // writer stageKażde wywołanie trafia do innej odpowiedzialności. Dwie różne drogi treści zasilają ten sam model. Dokładnie jeden etap — save() — zamienia model w bajty pliku. Nic w miejscu wywołania nie musi wiedzieć, jak budowana jest tablica odsyłaczy.
Częste nieporozumienie
Dział zatytułowany „Częste nieporozumienie”Często błędnie zakłada się, że „potok” oznacza strumieniowe API typu push, które łączy się etap po etapie, jak potok uniksowy. Tak nie jest. Potok jest tu architektonicznym rozkładem na części: etapy mają pojedyncze odpowiedzialności i typowane granice. Nadal korzysta się z płynnej fasady. Etapy to sposób budowania i testowania silnika, a nie transport składany ręcznie.
Pokrewnym błędem jest założenie, że fasada jest silnikiem. To punkt wejścia. Rzeczywista praca jest rozłożona na traity odpowiedzialności, dwie drogi treści oraz writer. Właśnie ten rozkład sprawia, że zmiana jednej funkcji nie naraża każdego wyniku na ryzyko.
Ograniczenia i granice
Dział zatytułowany „Ograniczenia i granice”Ta strona opisuje kształt potoku, a nie wewnętrzne API poszczególnych etapów. Dokładny spis traitów odpowiedzialności, reguły wyboru strategii writera oraz pola modelu treści definiują kod i dokumentacja referencyjna, nie to wyjaśnienie. Dokładna liczba traitów jest szczegółem implementacyjnym, który może się zmienić bez zmiany modelu. Ta strona nie obejmuje wewnętrznych etapów silnika HTML (osobny temat) ani strumieniowania i zachowania pamięci writera (również osobno). Twierdzenia strukturalne są aktualne na dzień przeglądu tej strony; autorytatywnym źródłem są katalogi repozytorium rdzenia src/Core/, src/Html/, src/Graphics/ oraz src/Writer/.
Model potoku jest identyczny we wszystkich edycjach; edycje dodają możliwości w obrębie etapów, a nie nowe etapy:
| Edition | Availability |
|---|---|
| Core | Core implementuje pełny potok: fasada → treść → writer. |
| Pro | Pro dodaje możliwości w obrębie istniejących etapów, a nie nowe etapy. |
| Enterprise | Enterprise dodaje możliwości w obrębie istniejących etapów, a nie nowe etapy. |
Powiązane dokumenty
Dział zatytułowany „Powiązane dokumenty”- Pamięć i strumieniowanie — jak etap writera utrzymuje pamięć w granicach.
- Potok HTML — wewnętrzne etapy drogi treści HTML.
- Ścisłe typy, wszędzie — typowane granice, które sprawiają, że każdy etap jest niezależnie testowalny.
Słowniczek
Dział zatytułowany „Słowniczek”- Fasada — publiczny punkt wejścia
Document: płynny, jednorazowy konstruktor, który zapisuje intencję i deleguje zadania do traitów odpowiedzialności. - Trait odpowiedzialności — wyspecjalizowany trait PHP komponowany przez fasadę; każdy jest właścicielem jednego obszaru funkcji (wyjście tekstu, rysowanie, strony, zabezpieczenia i tak dalej).
- Droga treści — jeden z dwóch sposobów, w jaki treść trafia do modelu: bezpośrednie rysowanie albo silnik HTML/CSS.
- Model dokumentu — wewnętrzny, typowany stan obejmujący strony, treść i zasoby silnika przed serializacją.
- Etap writera — komponent, który serializuje model do poprawnego pliku PDF, wybierając strategię PDF 1.4 / 1.7 / 2.0.
- Bezpieczny dla wątków roboczych — zaprojektowany tak, by stan o zasięgu procesu był bezpiecznie współdzielony, podczas gdy stan na żądanie jest tworzony od nowa i nigdy nie jest ponownie używany.