Contratti / Documento
In breve
Sezione intitolata “In breve”Il dominio document riunisce i contratti su cui costruire i PDF: PdfDocumentInterface per i contenuti, DocumentFactoryInterface per la creazione thread-safe nei worker, i contratti dei registri di font e immagini e i tre enum per consegna e impaginazione. Tutti sono stable a partire dalla versione 1.0.0 o 1.7.0.
Installazione
Sezione intitolata “Installazione”composer require nextpdf/core:^3Panoramica concettuale
Sezione intitolata “Panoramica concettuale”PdfDocumentInterface è la superficie API principale. Definisce la gestione delle pagine, la selezione dei font, l’impaginazione del testo in celle singole e multiple, il rendering HTML, l’incorporamento delle immagini e l’output finale. Ogni metodo restituisce static, quindi le chiamate possono essere concatenate. Document::createStandalone() restituisce un’istanza concreta che soddisfa l’interfaccia. Usare il type hint dell’interfaccia nei propri servizi: in questo modo le parti interne del motore restano sostituibili.
La creazione dei documenti segue due percorsi. In una richiesta PHP-FPM tradizionale, createStandalone() costruisce un documento autonomo con registri privati. Un worker a lunga esecuzione usa l’altro percorso. Rientrano in questo caso RoadRunner, Swoole e Laravel Octane. In questo scenario, DocumentFactoryInterface::create() restituisce un nuovo Document usa e getta. Il documento legge dai registri che vivono quanto il processo, ma non li modifica mai. La factory mantiene i singleton FontRegistryInterface e ImageRegistryInterface. Ogni documento ottiene il proprio contesto di rendering e il proprio writer. Questo realizza il contenimento dei guasti. Un documento non può corrompere lo stato condiviso da cui dipende un altro documento.
I contratti dei registri permettono a un worker di restare veloce. FontRegistryInterface analizza un file di font una sola volta e memorizza nella cache i metadati analizzati per l’intera durata del processo. Può essere bloccato dopo il warmup, in modo che il traffico di produzione non possa modificarlo. ImageRegistryInterface memorizza nella cache i dati binari delle immagini decodificate secondo un criterio LRU (Least Recently Used) con capacità limitata. I metadati delle immagini restano residenti anche dopo l’eliminazione dei dati binari. Entrambi espongono memoryUsage() per la pianificazione della capacità. ImageRegistryInterface estende ResettableService. Quel contratto elimina i dati memorizzati nella cache senza distruggere i metadati strutturali. Un worker può svuotare le cache delle immagini quando la memoria è sotto pressione e continuare a rispondere.
Tre enum completano il dominio. OutputDestination seleziona la visualizzazione inline, il download forzato, la scrittura su file system o la restituzione di una stringa raw. Orientation seleziona l’orientamento verticale od orizzontale. Alignment seleziona il testo allineato a sinistra, al centro, a destra o giustificato. Ogni enum espone i propri casi usando il codice TCPDF legacy come valore dell’enum. Il bridge compat-tcpdf può quindi applicare una mappatura pulita. La garanzia di compatibilità con le versioni precedenti per questi enum è additiva. Nessun caso viene rimosso. Nuovi casi possono essere introdotti in una release minore.
Superficie API
Sezione intitolata “Superficie API”| Tipo | Genere | Membri chiave | Stabilità | Da |
|---|---|---|---|---|
PdfDocumentInterface | interface | addPage(), setMargins(), setFont(), cell(), multiCell(), writeHtml(), image(), output(), save() | stable | 1.0.0 |
DocumentFactoryInterface | interface | create(?Config): Document | stable | 1.7.0 |
ResettableService | interface | reset(): void | stable | 1.7.0 |
FontRegistryInterface | interface | register(), get(), warmup(), lock(), isLocked(), registerFromBinary(), memoryUsage() | stable | 1.7.0 |
ImageRegistryInterface | interface | load(), loadFromString(), getMetadata(), memoryUsage() (estende ResettableService) | stable | 2.0.0 |
OutputDestination | enum (string) | Inline, Download, File, String | stable | 1.0.0 |
Orientation | enum (string) | Portrait, Landscape | stable | 1.0.0 |
Alignment | enum (string) | Left, Center, Right, Justify | stable | 1.0.0 |
FontRegistryInterface e ImageRegistryInterface sono documentati per intero nella pagina della tipografia; questa pagina document ne descrive il ruolo nel ciclo di vita della creazione.
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->setFont('helvetica', '', 12);$doc->cell(0, 10, 'This is a minimal PDF generated with NextPDF.', newLine: true);$doc->save(__DIR__ . '/output/01-hello-world.pdf');Esempio di codice — Produzione
Sezione intitolata “Esempio di codice — Produzione”<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\PdfFactory;use NextPDF\ValueObjects\{Margin, PageSize};
$factory = PdfFactory::new() ->withPageSize(PageSize::A4()) ->withMargins(new Margin(15.0, 15.0, 15.0, 15.0)) ->withCompress(true) ->withLang('en');
// The same configured factory creates independent documents.$doc = $factory->create();$doc->setTitle('PdfFactory Example');$doc->setAuthor('NextPDF');$doc->addPage();$doc->setFont('helvetica', '', 16);$doc->cell(0, 12, 'Created via PdfFactory', newLine: true);
$doc2 = $factory->create();$doc2->addPage();$doc2->setFont('helvetica', '', 12);$doc2->cell(0, 10, 'Second document from the same factory.');
$doc->save(__DIR__ . '/output/02-pdf-factory.pdf');PdfFactory è il builder immutabile; ogni with*() restituisce una nuova istanza. Compone internamente un DocumentFactoryInterface, quindi il modello dei registri per i worker descritto nella panoramica si applica senza ulteriore configurazione.
Casi limite e insidie
Sezione intitolata “Casi limite e insidie”createStandalone()costruisce registri privati. In un loop worker, questo comporta l’analisi di ogni font a ogni richiesta. Usare inveceDocumentFactoryInterfacecon registri condivisi.- Un
Documentè usa e getta per progettazione. Riutilizzare una singola istanza per documenti logici diversi provoca una propagazione indebita dello stato. Chiamarecreate()per ogni documento e lasciare che il garbage collector lo recuperi. FontRegistryInterface::lock()fa sì cheregister(),addFontDirectory()ewarmup()generino unaLogicException. Bloccare dopo il warmup, mai durante la gestione della richiesta.OutputDestination::Filescrive sul file system del server e restituisce i byte raw.save()è il percorso file esplicito. Non combinare i due approcci per lo stesso documento.cell()accettabool|stringper l’argomento del bordo a fini di compatibilità con TCPDF; una stringa vuota non è la stessa cosa difalse. Passare il valore tipizzato previsto.
Prestazioni
Sezione intitolata “Prestazioni”I registri di font e immagini rendono il dominio document un sistema con memoria limitata, invece di un modello legato alla singola richiesta. L’analisi dei font alla prima richiesta è l’operazione predominante. Il performance_budget è di 1500 ms di wall time e 64 MB di picco su tre documenti nell’esempio worker. Quasi tutto questo budget è dovuto alla prima analisi dei font. Dopo il warmup, il costo attribuibile al contratto per ogni documento è O(1): una ricerca nel registro e un’allocazione di contesto. memoryUsage() su uno dei due registri restituisce un MemoryReport per la pianificazione della capacità in tempo reale. ResettableService::reset() limita il picco di memoria sotto carico prolungato.
Note di sicurezza
Sezione intitolata “Note di sicurezza”I contratti document non presentano alcuna superficie crittografica, ma comportano due rischi operativi. Primo, image() accetta un percorso o un URL. In scenari con input non attendibile, limitare il recupero remoto tramite ExternalResourcePolicyInterface (vedere la pagina security-policy) anziché passare direttamente URL controllati dall’utente. Secondo, writeHtml() è il punto di ingresso della pipeline HTML. Il markup non attendibile deve passare attraverso un HtmlSecurityPolicyInterface prima del rendering. Il livello document di per sé non esegue la sanitizzazione. Questa responsabilità appartiene al dominio security-policy ed è modellata come contratto, in modo da poter fornire un criterio più restrittivo senza ricorrere a un fork.
Conformità
Sezione intitolata “Conformità”I contratti document implementano la struttura dei documenti PDF 2.0 come definita dalla norma ISO 32000-2. La gestione di output, pagine e font produce oggetti indiretti e un flusso di riferimenti incrociati secondo ISO 32000-2 §7. Il contenuto viene emesso tramite il livello writer secondo il contratto del livello motore (ADR-010). In questa pagina non viene asserita alcuna dichiarazione a livello di clausola oltre alla conformità strutturale. La conformità PDF/A e PDF/UA è documentata nelle pagine relative all’estrazione e all’accessibilità, che riportano le tabelle normative.
Vedere anche
Sezione intitolata “Vedere anche”- Contratti: 41 interfacce pubbliche (SPI) — panoramica SPI e livelli di stabilità.
- Contratti / Tipografia — documentazione completa di
FontRegistryInterface. - Contratti / Criterio di sicurezza — i criteri che regolano
writeHtml()eimage(). - Core — le classi concrete
DocumentePdfFactory. - Document — il modulo di costruzione dei documenti.
- Writer — il livello che emette gli oggetti PDF per questi contratti.