Kontrakty: 41 publicznych interfejsów (SPI)
W skrócie
Dział zatytułowany „W skrócie”NextPDF\Contracts to publiczny interfejs dostawcy usług (SPI): obejmuje 41 interfejsów i typów wyliczeniowych w katalogu src/Contracts/, z jawnym znacznikiem @stability oraz obietnicą zgodności wstecznej. Pakiety rozszerzeń, mostki frameworków oraz edycje Pro i Enterprise zależą od tych typów, a nigdy od konkretnych klas.
Instalacja
Dział zatytułowany „Instalacja”composer require nextpdf/core:^3Przegląd koncepcyjny
Dział zatytułowany „Przegląd koncepcyjny”Silnik udostępnia dwie powierzchnie. Konkretne klasy w katalogach src/Core/, src/Html/ i src/Writer/ nie są objęte obietnicą zgodności i mogą się zmieniać między wydaniami pomocniczymi. Przestrzeń nazw Contracts działa inaczej: to wyselekcjonowany zbiór typów z sygnaturami zamrożonymi dla deklarowanego poziomu stabilności. Wszystko, co znajduje się poza silnikiem, zależy od tej przestrzeni nazw i od niczego głębiej. Dotyczy to mostków Laravel, Symfony i CodeIgniter, warstwy zgodności compat-tcpdf, serwera NextPDF Server oraz edycji Pro i Enterprise.
Każdy kontrakt deklaruje w swoim bloku PHPDoc jeden z czterech poziomów. Kontrakt stable nie dopuszcza żadnej zmiany łamiącej zgodność w wydaniu pomocniczym ani poprawkowym. Nowe metody pojawiają się wyłącznie z implementacjami domyślnymi. Kontrakt experimental może się zmienić w wydaniu pomocniczym wraz z informacją o wycofaniu. Kontrakt deprecated wskazuje swój zamiennik. Niewielką część stanowią typy wyłącznie kontraktowe, takie jak StreamingWriterInterface i CursorInterface. Taki typ jest opublikowany i zamrożony, ale nie ma jeszcze żadnej implementacji produkcyjnej.
Autorytatywną listą poziomów jest docs/extension-points.json (wersja manifestu 3.0.0, 67 opublikowanych punktów w przestrzeniach Contracts i Event). Maszynowo weryfikowalny test, tests/Unit/Contracts/StabilityContractTest.php, odczytuje ten manifest i przerywa budowanie w pięciu przypadkach. Po pierwsze, gdy brakuje wymienionego typu. Po drugie, gdy odzwierciedlony rodzaj jest niezgodny z manifestem. Po trzecie, gdy znacznik PHPDoc @stability jest rozbieżny z manifestem. Po czwarte, gdy kontraktu z katalogu src/Contracts/ brakuje w manifeście. Po piąte, gdy trafi do niego typ @internal. Powierzchnia kontraktów nie może więc niezauważenie odbiec od manifestu.
Kontrakty dzielą się na dziewięć domen, z których każda ma dedykowaną stronę: konstrukcja dokumentu, podpisywanie, kodowanie kodów kreskowych, typografia, polityka bezpieczeństwa, ekstrakcja, obserwowalność i strumieniowanie. Podział odzwierciedla sposób, w jaki wdraża się silnik w praktyce. Do generowania plików w formacie Portable Document Format (PDF) służy kontrakt dokumentu. Do dodania podpisu służą kontrakty podpisywania. Do ograniczenia niezaufanego kodu HTML służą kontrakty polityki bezpieczeństwa.
Rozwiązywanie opcjonalnych implementacji przebiega w całym silniku według jednego wzorca. Pakiet Core sprawdza obecność konkretnej klasy za pomocą class_exists() i rzutuje ją na kontrakt. W ten sposób LtvManagerInterface i PdfAManagerInterface są rozwiązywane do implementacji z edycji Pro. Pakiet Core pozostaje na licencji Apache-2.0, bez twardej zależności od kodu komercyjnego.
Powierzchnia API
Dział zatytułowany „Powierzchnia API”| Kontrakt | Rodzaj | Stabilność | Od wersji | Domena |
|---|---|---|---|---|
PdfDocumentInterface | interface | stable | 1.0.0 | document |
DocumentFactoryInterface | interface | stable | 1.7.0 | document |
ResettableService | interface | stable | 1.7.0 | document |
OutputDestination | enum | stable | 1.0.0 | document |
Orientation | enum | stable | 1.0.0 | document |
Alignment | enum | stable | 1.0.0 | document |
SignerInterface | interface | stable | 1.0.0 | signing |
HsmSignerInterface | interface | stable | 1.0.0 | signing |
DeferredSignerInterface | interface | experimental | 3.0.0 | signing |
TimestampProviderInterface | interface | experimental | 3.0.0 | signing |
LtvManagerInterface | interface | stable | 1.10.0 | signing |
CryptoPolicyInterface | interface | stable | 1.9.0 | signing |
Barcode1DEncoderInterface | interface | stable | 1.0.0 | barcode |
Barcode2DEncoderInterface | interface | stable | 1.0.0 | barcode |
BarcodeEncoderInterface | interface | stable | 3.0.0 | barcode |
Gs1DataParserInterface | interface | stable | 1.0.0 | barcode |
FontRegistryInterface | interface | stable | 1.7.0 | typography |
TextPreprocessorInterface | interface | stable | 1.9.0 | typography |
HtmlSecurityPolicyInterface | interface | stable | 3.1.0 | security-policy |
ExternalResourcePolicyInterface | interface | stable | 4.0.0 | security-policy |
InspectorInterface | interface | experimental | 2.2.0 | extraction |
EmbeddingServiceInterface | interface | experimental | 2.1.0 | extraction |
VectorIndexInterface | interface | experimental | 2.1.0 | extraction |
JobNotificationInterface | interface | experimental | 2.2.0 | observability |
SpectrumInterface | interface | experimental | 2.1.0 | observability |
StreamingWriterInterface | interface | experimental | 3.1.0 | streaming |
CursorInterface | interface | experimental | 3.1.0 | streaming |
Tabela wymienia podstawowe kontrakty. Pozostałe typy, w tym obiekty transferu danych (DTO) typu value object (TextSegment, TextPreprocessResult), podprzestrzeń nazw EInvoice, typy wyliczeniowe opisujące zachowanie (DegradationPolicy, UnderlineStyle) oraz kontrakty importu (ImportedFormObjectInterface, EmbeddedPdfObjectInterface, ChromeRenderResultInterface), są udokumentowane na stronach domen w sekcji Zobacz też. Pełna lista w formacie odczytywalnym maszynowo to docs/extension-points.json, odzwierciedlona w .ai/contracts-map.md.
Przykład kodu — szybki start
Dział zatytułowany „Przykład kodu — szybki start”<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Hello World');$doc->addPage();$doc->setFont('helvetica', '', 24);$doc->cell(0, 15, 'Hello, NextPDF!', newLine: true);$doc->save(__DIR__ . '/output/01-hello-world.pdf');Document::createStandalone() zwraca konkretny obiekt Document, który spełnia PdfDocumentInterface. W usługach deklaruj typ interfejsu, aby wewnętrzne elementy silnika pozostały wymienne.
Przykład kodu — produkcja
Dział zatytułowany „Przykład kodu — produkcja”<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\DocumentFactory;use NextPDF\Core\PdfFactory;use NextPDF\Graphics\ImageRegistry;use NextPDF\Typography\FontRegistry;
// Created once at process boot in a RoadRunner/Swoole/Octane worker.$fontRegistry = new FontRegistry();$imageRegistry = new ImageRegistry(maxCacheBytes: 50 * 1024 * 1024);$documentFactory = new DocumentFactory($fontRegistry, $imageRegistry);
$factory = PdfFactory::new() ->withCompress(true) ->withDocumentFactory($documentFactory);
for ($request = 1; $request <= 3; $request++) { $doc = $factory->create(); $doc->setTitle("Worker Request #{$request}"); $doc->addPage(); $doc->setFont('helvetica', 'B', 16); $doc->cell(0, 12, "Worker Request #{$request}", newLine: true); $doc->save(__DIR__ . "/output/14-worker-request-{$request}.pdf");}DocumentFactory implementuje DocumentFactoryInterface. Przechowuje singletony FontRegistryInterface i ImageRegistryInterface o cyklu życia procesu i wstrzykuje je do każdego jednorazowego obiektu Document, dzięki czemu proces roboczy parsuje każdą czcionkę tylko raz na tysiące żądań.
Przypadki brzegowe i pułapki
Dział zatytułowany „Przypadki brzegowe i pułapki”- Typ wyłącznie kontraktowy przechodzi kompilację, ale nie ma żadnego oparcia w czasie wykonania. Użycie
newwobecStreamingWriterInterfacelubCursorInterfacenie może się powieść, ponieważ żadna klasa jeszcze ich nie implementuje. Traktuj je jako wstępnie zadeklarowany interfejs programowania aplikacji (API). - Znacznik PHPDoc
@stabilityjest źródłem prawdy dla pojedynczego typu.docs/extension-points.jsonjest źródłem prawdy dla całego zbioru. Gdy staną się rozbieżne,StabilityContractTestkończy się niepowodzeniem. Nie ukrywaj tej rozbieżności, edytując tylko jedną stronę. - W praktyce
experimentalnie oznacza niestabilności. Oznacza, że obietnica zgodności jest słabsza. Zanim zaczniesz na nim polegać, przeczytaj polebc_promisekażdego kontraktu w.ai/contracts-map.md. - Klasa
@internalnigdy nie jest kontraktem, nawet jeśli inne pakiety technicznie mogą się do niej odwoływać. Test stabilności odrzuca każdy typ@internal, który pojawia się w manifeście. - Dodanie metody do interfejsu
stablejest zmianą łamiącą zgodność dla implementujących go klas, chyba że metoda jest dostarczana z implementacją domyślną. Silnik dodaje możliwości poprzez nowe interfejsy, a nie przez rozszerzanie istniejących.
Wydajność
Dział zatytułowany „Wydajność”Programowanie oparte na Contracts nie dodaje mierzalnego kosztu w czasie wykonania: podpowiedź typu dla interfejsu jest rozwiązywana na etapie łączenia, a nie przy każdym wywołaniu. performance_budget dla przykładu z procesem roboczym na tej stronie wynosi 1500 ms czasu rzeczywistego i 64 MB szczytowego zużycia pamięci dla trzech dokumentów. W tym budżecie dominuje parsowanie czcionek przy pierwszym żądaniu. Późniejsze żądania ponownie wykorzystują pamięć podręczną rejestru, a czas przypisywany pracy kontraktów spada do jednocyfrowej liczby milisekund. Model kosztu to O(1) na każde wywołanie kontraktu; właściwa praca odbywa się w konkretnej implementacji, udokumentowanej na każdej stronie domeny.
Uwagi dotyczące bezpieczeństwa
Dział zatytułowany „Uwagi dotyczące bezpieczeństwa”SPI jest również granicą bezpieczeństwa. HtmlSecurityPolicyInterface i ExternalResourcePolicyInterface to kontrakty działające na zasadzie odmowy domyślnej, które ograniczają to, co może zrobić niezaufany kod HTML, zanim dotrze do mechanizmu renderującego. CryptoPolicyInterface kontroluje wybór algorytmu i siły klucza dla podpisywania oraz szyfrowania. Ponieważ są to kontrakty, można dostarczyć bardziej restrykcyjną politykę bez rozgałęziania silnika. W przypadku każdej polityki istotnej dla bezpieczeństwa opieraj się na poziomie stable. Eksperymentalne kontrakty polityki mogą zmieniać kształt API między wydaniami pomocniczymi. Strony domen podpisywania i polityki bezpieczeństwa zawierają pełny model zagrożeń oraz odniesienia normatywne.
Zgodność
Dział zatytułowany „Zgodność”Niniejszy przegląd nie formułuje żadnego bezpośredniego twierdzenia normatywnego; każda strona domeny renderuje własny blok citations. Kontrakty podpisywania odpowiadają ISO 32000-2 §12.8 (podpisy cyfrowe) oraz ETSI EN 319 142 (profile bazowe PAdES). Menedżer PDF/A odpowiada ISO 19005-4. Tabele zgodności na poziomie klauzul znajdziesz na stronach podpisywania, polityki bezpieczeństwa i ekstrakcji.
Kontekst komercyjny
Dział zatytułowany „Kontekst komercyjny”Edycje Pro i Enterprise dostarczają kod produkcyjny obsługujący kilka kontraktów z pakietu Core: LtvManagerInterface (walidacja długoterminowa), PdfAManagerInterface (egzekwowanie PDF/A), sprzętowy moduł bezpieczeństwa (HSM) i odroczone podpisy, kodery kodów kreskowych oraz kontrakty osadzania i indeksu wektorowego. Pakiet Core publikuje i zamraża interfejs; pakiet Premium dostarcza implementację. Dzięki temu silnik open source pozostaje na licencji Apache-2.0, a wdrożenia komercyjne otrzymują aktualizację drop-in bez zmiany API.
Zobacz też
Dział zatytułowany „Zobacz też”- Contracts / Document — kontrakty dokumentu PDF, fabryki i rejestru.
- Contracts / Signing — kontrakty podpisującego, HSM, znacznika czasu i walidacji długoterminowej (LTV).
- Contracts / Security Policy — kontrakty polityki kryptograficznej, HTML i zasobów.
- Contracts / Typography — kontrakty rejestru czcionek i wstępnego przetwarzania tekstu.
- Contracts / Extraction — kontrakty inspektora, PDF/A, osadzania i e-faktur.
- Core — konkretne klasy spełniające te kontrakty.
- Event — odpowiednik SPI dla zdarzeń, publikowany wraz z
Contracts.