Contratti: 41 interfacce pubbliche (SPI)
In sintesi
Sezione intitolata “In sintesi”NextPDF\Contracts è l’interfaccia pubblica service-provider (SPI): 41 interfacce ed enum sotto src/Contracts/, ciascuno con un tag @stability esplicito e una promessa di compatibilità all’indietro. I pacchetti di estensione, i bridge per i framework e le edizioni Pro ed Enterprise programmano contro questi tipi, mai contro classi concrete.
Installazione
Sezione intitolata “Installazione”composer require nextpdf/core:^3Panoramica concettuale
Sezione intitolata “Panoramica concettuale”Il motore separa due superfici. Le classi concrete sotto src/Core/, src/Html/ e src/Writer/ non offrono alcuna promessa di compatibilità e possono cambiare liberamente tra le versioni minori. Lo spazio dei nomi Contracts è l’opposto: un insieme curato di tipi le cui firme sono congelate in base al livello di stabilità dichiarato. Tutto ciò che vive all’esterno del motore dipende da questo spazio dei nomi e da nulla di più interno. Questo include i bridge per Laravel, Symfony e CodeIgniter, lo shim compat-tcpdf, NextPDF Server e le edizioni Pro ed Enterprise.
Ogni contratto dichiara nel proprio PHPDoc uno di quattro livelli. Un contratto stable non ammette modifiche incompatibili in una release minore o patch. I nuovi metodi vengono introdotti solo con implementazioni predefinite. Un contratto experimental può cambiare in una release minore con un avviso di deprecazione. Un contratto deprecated indica il proprio sostituto. Un numero limitato di tipi, come StreamingWriterInterface e CursorInterface, esiste solo come contratto. Il tipo è pubblicato e congelato, ma non viene ancora distribuita alcuna implementazione di produzione.
L’elenco autorevole dei livelli è docs/extension-points.json (manifest versione 3.0.0, 67 punti pubblicati tra Contracts ed Event). Un test verificabile automaticamente, tests/Unit/Contracts/StabilityContractTest.php, legge quel manifest. Fa fallire la build in cinque condizioni. La prima è un tipo elencato che risulta mancante. La seconda è un tipo letto tramite reflection che non è allineato al manifest. La terza è un tag PHPDoc @stability che diverge dal manifest. La quarta è un contratto sotto src/Contracts/ che è assente dal manifest. La quinta è un tipo @internal che finisce nel manifest. La superficie dei contratti non può divergere senza essere rilevata.
I contratti rientrano in nove domini. Ciascuno ha una pagina dedicata: costruzione del documento, firma, codifica dei codici a barre, tipografia, criteri di sicurezza, estrazione, osservabilità e streaming. La suddivisione rispecchia il modo in cui un integratore adotta il motore. Per generare i PDF si dipende dal contratto del documento. Per aggiungere una firma si dipende dai contratti di firma. Per vincolare l’HTML non attendibile si dipende dai contratti dei criteri di sicurezza.
La risoluzione di un’implementazione opzionale segue un unico schema in tutto il motore. Il core verifica la presenza di una classe concreta con class_exists() e la usa tramite il contratto. LtvManagerInterface e PdfAManagerInterface risolvono in questo modo le loro implementazioni Pro. Il core rimane pertanto Apache-2.0 senza alcuna dipendenza rigida da codice commerciale.
Superficie dell’API
Sezione intitolata “Superficie dell’API”| Contratto | Tipo | Stabilità | Da | Dominio |
|---|---|---|---|---|
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 |
La tabella elenca i contratti principali. I tipi rimanenti — i DTO value-object (TextSegment, TextPreprocessResult), il sottospazio dei nomi EInvoice, gli enum di comportamento (DegradationPolicy, UnderlineStyle) e i contratti di importazione (ImportedFormObjectInterface, EmbeddedPdfObjectInterface, ChromeRenderResultInterface) — sono documentati nelle pagine di dominio indicate in Vedere anche. L’elenco completo leggibile dalla macchina è docs/extension-points.json, rispecchiato in .ai/contracts-map.md.
Esempio di codice — Avvio rapido
Sezione intitolata “Esempio di codice — Avvio rapido”<?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() restituisce un Document concreto che soddisfa PdfDocumentInterface. Dichiarare l’interfaccia come tipo nei propri servizi, così che gli interni del motore restino sostituibili.
Esempio di codice — Produzione
Sezione intitolata “Esempio di codice — Produzione”<?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 implementa DocumentFactoryInterface. Mantiene istanze singleton di FontRegistryInterface e ImageRegistryInterface per la durata del processo e le inietta in ogni Document a vita breve, così che un worker analizzi ogni font una sola volta su migliaia di richieste.
Casi limite e insidie
Sezione intitolata “Casi limite e insidie”- Un tipo disponibile solo come contratto compila ma non ha alcun supporto a runtime.
newsuStreamingWriterInterfaceoCursorInterfacenon può riuscire perché nessuna classe li implementa ancora. Considerarli come un’API dichiarata in anticipo. - Il tag PHPDoc
@stabilityè la fonte autorevole per un singolo tipo.docs/extension-points.jsonè la fonte autorevole per l’insieme. Quando divergono,StabilityContractTestfallisce — non va nascosto il disaccordo modificando uno dei due lati. experimentalnon significa instabile nella pratica; significa che la promessa di compatibilità è più debole. Leggere il campobc_promisedi ogni contratto in.ai/contracts-map.mdprima di dipendervi.- Una classe
@internalnon è mai un contratto, anche se altri pacchetti possono tecnicamente farvi riferimento. Il test di stabilità rifiuta qualsiasi tipo@internalche compaia nel manifest. - Aggiungere un metodo a un’interfaccia
stableè una modifica che rompe la compatibilità per gli implementatori, a meno che il metodo non venga distribuito con un’implementazione predefinita. Il motore introduce funzionalità attraverso nuove interfacce, non ampliando quelle esistenti.
Prestazioni
Sezione intitolata “Prestazioni”Programmare contro Contracts non aggiunge alcun costo misurabile a runtime: un type-hint d’interfaccia si risolve al momento del collegamento, non a ogni chiamata. Il performance_budget per l’esempio worker di questa pagina è di 1500 ms di tempo reale e 64 MB di picco su tre documenti. L’analisi dei font alla prima richiesta domina tale budget. Le richieste successive riutilizzano la cache del registro e il lavoro attribuibile ai contratti scende a millisecondi a una cifra. Il modello di costo è O(1) per dispatch di contratto; il lavoro risiede nell’implementazione concreta, documentata in ciascuna pagina di dominio.
Note sulla sicurezza
Sezione intitolata “Note sulla sicurezza”L’SPI è anche un confine di sicurezza. HtmlSecurityPolicyInterface ed ExternalResourcePolicyInterface sono contratti deny-by-default che vincolano ciò che l’HTML non attendibile può fare prima di raggiungere un renderer. CryptoPolicyInterface controlla la scelta dell’algoritmo e della robustezza della chiave per la firma e la cifratura. Poiché sono contratti, un integratore può fornire un criterio più rigoroso senza creare un fork del motore. Vincolarsi al livello stable per qualsiasi criterio rilevante per la sicurezza. I contratti di criteri sperimentali possono cambiare forma tra le release minori. Le pagine di dominio relative alla firma e ai criteri di sicurezza riportano il modello di minaccia completo e i riferimenti normativi.
Conformità
Sezione intitolata “Conformità”Questa panoramica non formula alcuna pretesa normativa diretta; ogni pagina di dominio espone il proprio blocco citations. I contratti di firma corrispondono a ISO 32000-2 §12.8 (firme digitali) ed ETSI EN 319 142 (baseline PAdES). Il gestore PDF/A corrisponde a ISO 19005-4. Per le tabelle di conformità a livello di clausola, vedere le pagine relative alla firma, ai criteri di sicurezza e all’estrazione.
Contesto commerciale
Sezione intitolata “Contesto commerciale”Le edizioni Pro ed Enterprise forniscono le implementazioni di produzione dietro diversi contratti core: LtvManagerInterface (convalida a lungo termine), PdfAManagerInterface (applicazione del PDF/A), i firmatari Hardware Security Module (HSM) e differiti, gli encoder dei codici a barre e i contratti di embedding e di indice vettoriale. Il core pubblica e congela l’interfaccia; il pacchetto Premium distribuisce l’implementazione. Questo mantiene il motore open source Apache-2.0 offrendo al contempo alle distribuzioni commerciali un aggiornamento drop-in senza alcuna modifica dell’API.
Vedere anche
Sezione intitolata “Vedere anche”- Contratti / Documento — contratti per documento PDF, factory e registro.
- Contratti / Firma — contratti per signer, HSM, marca temporale e LTV.
- Contratti / Criteri di sicurezza — contratti per criteri crittografici, HTML e risorse.
- Contratti / Tipografia — contratti per registro dei font e pre-elaborazione del testo.
- Contratti / Estrazione — contratti per inspector, PDF/A, embedding ed e-invoice.
- Core — classi concrete che soddisfano questi contratti.
- Event — la controparte SPI degli eventi pubblicata insieme a
Contracts.