Pro edizione
Document — Riferimento approfondito
In sintesi
Sezione intitolata “In sintesi”Il modulo Document fornisce tre primitive di assemblaggio Pro: suddivisione per intervalli di pagine, unione multi-documento e costruzione del dizionario PDF Portfolio (Collection). PdfSplitter estrae gli intervalli di pagine in PDF autonomi e strutturalmente conformi e unisce interi documenti in un unico file rinumerato. PdfPortfolio costruisce il dizionario Collection che presenta i file incorporati con colonne di schema ordinabili. Ogni punto di ingresso limita la dimensione dell’input e il numero di oggetti a fronte di input ostile.
Disponibilità e licenza
Sezione intitolata “Disponibilità e licenza”Questa funzionalità è inclusa in NextPDF Pro (nextpdf/pro) e si attiva con un envelope di licenza di livello Pro. Un deployment privo di tale entitlement non carica le classi della funzionalità. Confronta le edizioni e ottieni una licenza.
Superficie API pubblica
Sezione intitolata “Superficie API pubblica”Tutti i tipi del modulo risiedono nel namespace NextPDF\Pro\Document. PageRange e MergeResult sono value object Core provenienti da NextPDF\Document.
| Simbolo | Parametri | Comportamento predefinito | Restituisce | Solleva o fallisce con | Note |
|---|---|---|---|---|---|
PdfSplitter::split() | string $pdfData, list<PageRange> $ranges, int $maxBytes = 100_000_000, int $maxRanges = 1000 | Costruisce un segmento PDF autonomo per ciascun intervallo | SplitResult | InvalidArgumentException se manca l’intestazione %PDF; OverflowException sul guard di dimensione, numero di intervalli o chiusura | I guard vengono eseguiti prima di qualsiasi parsing |
PdfSplitter::splitEvery() | string $pdfData, int $pagesPerSegment | Deriva intervalli contigui di N pagine; l’ultimo segmento può essere più corto | SplitResult | InvalidArgumentException quando $pagesPerSegment < 1 o manca l’intestazione | Delega a split() con i tetti predefiniti |
PdfSplitter::extractPages() | string $pdfData, PageRange $range | Restituisce un intervallo come byte PDF autonomi | string | InvalidArgumentException se manca l’intestazione; OverflowException sul guard di chiusura | Nessun parametro di tetto su questo percorso |
PdfSplitter::mergeDocuments() | list<string> $pdfs, int $maxInputs = 100, int $maxBytesEach = 100_000_000 | Unisce gli input nell’ordine dato in un unico PDF rinumerato | MergeResult | InvalidArgumentException su lista vuota o input non PDF; OverflowException sul guard di numero, dimensione per input o chiusura | Da 3.1.0; la versione di input più alta determina l’intestazione dell’output |
SplitResult | readonly $segments, $ranges, $totalPages | Trasporta i byte grezzi dei segmenti più i metadati di origine | — | — | Value object final readonly |
SplitResult::count() | — | Conta i segmenti prodotti | int | — | — |
SplitResult::segment() | int $index | Restituisce i byte di un segmento | string | OutOfRangeException su indice fuori intervallo | Indice a base zero |
PdfPortfolio::__construct() | string $viewMode = 'tile' | Convalida la modalità di visualizzazione in fase di costruzione | — | InvalidArgumentException su una modalità diversa da tile, detail, hidden | — |
PdfPortfolio::addSchema() | PortfolioField $field | Aggiunge una colonna di schema | self | — | Fluente |
PdfPortfolio::addEntry() | PortfolioEntry $entry | Aggiunge una voce di file | self | — | Fluente |
PdfPortfolio::getSchema() | — | Restituisce i campi di schema accumulati | list<PortfolioField> | — | — |
PdfPortfolio::getEntries() | — | Restituisce le voci di file accumulate | list<PortfolioEntry> | — | — |
PdfPortfolio::count() | — | Conta le voci di file | int | — | — |
PdfPortfolio::generateCollectionDictionary() | — | Emette la stringa del dizionario Collection | string | — | I blocchi di schema e ordinamento compaiono solo quando esistono campi |
PortfolioEntry | $filename, $data, $description = '', $mimeType = 'application/octet-stream', $customFields = [] | Value object immutabile di voce di file | — | — | size() restituisce la lunghezza in byte dei dati |
PortfolioField | $name, PortfolioFieldType $type, $displayName = '', $order = 0, $visible = true | Value object immutabile di colonna di schema | — | — | effectiveDisplayName() ripiega su $name |
PortfolioFieldType | Enum di stringa: Text, Date, Number, FileName, Description, Size, ModDate, CreationDate | Mappa ogni caso a un /Subtype PDF tramite pdfSubtype() | string (S, D, N, F, Desc) | — | I casi di tipo data condividono il subtype D; i casi numerici condividono N |
Firme dei punti di ingresso:
public function split(string $pdfData, array $ranges, int $maxBytes = 100_000_000, int $maxRanges = 1000): SplitResult
public function mergeDocuments( array $pdfs, int $maxInputs = 100, int $maxBytesEach = 100_000_000,): MergeResultpublic function __construct( private readonly string $viewMode = 'tile',)
public function generateCollectionDictionary(): stringContratto di comportamento
Sezione intitolata “Contratto di comportamento”Suddivisione e unione condividono un’unica pipeline di grafo di oggetti:
- L’input deve iniziare con l’intestazione
%PDF. I guard di dimensione e numero vengono eseguiti prima del parsing e sollevanoOverflowExceptionin caso di violazione. - Le pagine foglia vengono rilevate scansionando i marcatori di oggetto pagina; i nodi dell’albero delle pagine sono esclusi dal conteggio.
- Il parser indicizza ogni oggetto indiretto non compresso con una scansione dei terminatori consapevole degli stream. La prima occorrenza di un id di oggetto prevale, pertanto gli override da aggiornamento incrementale non vengono applicati.
- Gli attributi ereditabili dell’albero delle pagine (
/Resources,/MediaBox,/CropBox,/Rotate) vengono materializzati su ciascuna pagina estratta percorrendo la sua catena/Parent, così che i segmenti siano autonomi. - La chiusura transitiva dei riferimenti indiretti di ciascuna pagina viene raccolta, escludendo il back-edge
/Parent, e rinumerata in un nuovo spazio di id contiguo. - Il serializzatore emette l’intestazione, il Catalog, l’albero Pages, gli oggetti pagina e gli oggetti di chiusura, poi una tabella di cross-reference con offset accurati al byte e un
startxrefche punta alla parola chiavexref. mergeDocumentsripete la pipeline per ciascun input in un unico spazio di id condiviso. La versione PDF di input più alta determina l’intestazione dell’output. È la sostituzione conforme del merger Core disattivato, che rimane fail-closed.- L’output è deterministico. Non vengono emessi timestamp né identificatori casuali, quindi input identici producono byte identici.
Assemblaggio del Portfolio:
- Il costruttore convalida la modalità di visualizzazione. Il token
/Viewemesso è/T,/Do/Hrispettivamente per tile, detail e hidden. generateCollectionDictionary()emette/Type /Collection, il token/View, un blocco/Schemaquando esistono campi e una direttiva/Sortsul primo campo dello schema, crescente.- Ciascun campo dello schema emette
/Subtype(dapdfSubtype()),/N(nome visualizzato con escape),/O(ordine) e/V(visibilità). - I nomi dei campi vengono ripuliti in token di nome PDF validi; i caratteri non alfanumerici diventano underscore. I valori stringa vengono sottoposti a escape come stringhe letterali PDF.
- Le voci di file sono esposte tramite
getEntries()per l’incorporamento da parte del livello di scrittura. Il dizionario Collection stesso trasporta solo visualizzazione, schema e ordinamento.
Casi limite e modalità di errore
Sezione intitolata “Casi limite e modalità di errore”- Un intervallo che non corrisponde ad alcuna pagina produce un segmento minimale di una pagina (MediaBox 612 x 792), non un errore.
- Un documento senza marcatori di pagina rilevabili viene conteggiato come una pagina.
- Le pagine memorizzate all’interno di object stream non vengono rilevate; solo gli oggetti indiretti non compressi partecipano all’estrazione.
- Quando esistono id di oggetto duplicati, viene usata la revisione con offset più basso; le revisioni successive da aggiornamento incrementale vengono ignorate.
- La chiusura dei riferimenti per segmento è limitata a 50.000 oggetti; un grafo maliziosamente auto-referenziale o a fan-out solleva
OverflowException. - Tetti predefiniti: 100 MB di input, 1.000 intervalli, 100 input di unione. Tutti sono regolabili da chi effettua la chiamata per ogni chiamata.
splitEvery()rifiuta una dimensione di segmento inferiore a 1 conInvalidArgumentException.SplitResult::segment()rifiuta un indice fuori intervallo conOutOfRangeException.- Due nomi di campo dello schema che differiscono solo per la punteggiatura vengono ripuliti nella stessa chiave di dizionario; il campo successivo oscura silenziosamente quello precedente nello schema emesso.
- Questo modulo non esegue alcuna operazione crittografica; la modalità FIPS non ne altera il comportamento.
Conformità
Sezione intitolata “Conformità”L’output dei segmenti e delle unioni segue il modello degli oggetti pagina di ISO 32000-2; il sorgente annota le clausole pertinenti. Asserzioni verificabili esternamente:
- Il layout del trailer, l’offset di byte di
startxrefe il terminatore%%EOFseguono ISO 32000-2:2020, §7.5.5 — referenceef0f2a4b563b84f81b3e6428612bc47c510d94fc8096849d339abf0f3247d845. - I valori
/Viewdel dizionario Collection (/T,/D,/H) seguono ISO 32000-2:2020, §12.3.5 — reference5cefaaeb40f3ff98e3aba135ac57c9424a05c43144c1b9b5156bfd4295e08ddd. - Le voci
/Subtype,/N,/Oe/Vdei campi Collection seguono ISO 32000-2:2020, §12.3.5 (collection field dictionary) — reference6300fbfdc8a913a8dc6f6ae34eff99f2bd03c4313a77777cdd5a8dd856d9537a.
Queste dichiarazioni descrivono capacità implementate e verificate dai test del modulo. Il supporto di un costrutto non è un’asserzione di conformità, e la conformità non è certificazione; NextPDF non detiene alcuna certificazione di terze parti per questo modulo.
Note di sviluppo
Sezione intitolata “Note di sviluppo”- Tutte le classi del modulo sono
final; i tipi di risultato e i value object sonoreadonly. I tipi splitter e Portfolio risalgono a 1.9.0;mergeDocuments()è stato aggiunto in 3.1.0. PageRangeeMergeResultsono tipi Core, quindi i punti di chiamata restano portabili tra edizioni.- I trailer dei segmenti trasportano solo
/Sizee/Root; non viene emesso alcun identificatore di file/IDné dizionario/Info. - Per i flussi di lavoro di aggiornamento incrementale o firma, passare i byte dei segmenti al modulo Writer anziché modificarli in place.
- Il modulo non registra alcun contenuto del documento.
Confine di pubblicazione
Sezione intitolata “Confine di pubblicazione”Questa pagina documenta solo il comportamento osservabile esternamente e la superficie API pubblica supportata. Percorsi di namespace interni, classi di supporto, tabelle di meccanismo, nomi di file di runbook e prefissi di ticket sono fuori ambito.