Un PDF è un contenitore: file incorporati e dati associati
Spec: ISO 32000-2, §7.11.4ISO 32000-2 §7.11.4Spec: ISO 32000-2, §14.13ISO 32000-2 §14.13Spec: ISO 19005-3, PDF/A-3ISO 19005-3 PDF/A-3
In sintesi
Sezione intitolata “In sintesi”La maggior parte delle persone immagina un PDF come una pila di pagine. Quella è la parte che si vede. Ma un PDF è anche un contenitore, e può trasportare interi altri file al suo interno — un foglio di calcolo, un payload XML, il documento sorgente originale — raggruppati nello stesso unico file che si consegna a qualcun altro.
Questa pagina spiega come funziona: l’embedded-file stream che memorizza i byte, il name tree che li elenca, e l’unica chiave che decide se un allegato è semplicemente lì o significa davvero qualcosa.
Perché è importante
Sezione intitolata “Perché è importante”Un allegato non tipizzato e uno tipizzato sembrano identici a un essere umano. Entrambi sono un file che viaggia dentro un PDF e — in questo motore — entrambi sono associati al documento. La differenza è che uno dei due dice a una macchina a cosa serve, e l’altro lascia la relazione in bianco affinché la macchina la indovini.
Quella differenza è tutta la partita per una e-fattura ibrida. Una piattaforma fiscale non legge la pagina della fattura; legge l’XML che si è incorporato. Se quell’XML è allegato come un blob indifferenziato anziché come i dati della fattura per il documento visibile, un lettore conforme non ha modo affidabile di sapere che è il payload da elaborare. La pagina sembra perfetta. La fattura viene respinta. Il fallimento arriva giorni dopo, con un pagamento sospeso alle spalle.
Azzeccare la relazione, nello strato che produce il file, è molto più economico che scoprirla una fattura respinta alla volta.
In breve
Sezione intitolata “In breve”- Un PDF può incorporare i byte di qualsiasi file come embedded file stream (Spec: ISO 32000-2, §7.11.4ISO 32000-2 §7.11.4). Lo stream porta i dati più un piccolo parameters dictionary: dimensione originale, date e un checksum.
- I file incorporati sono catalogati nel name tree
EmbeddedFiles, così che un lettore possa enumerarli per nome senza scandire l’intero documento. - Un file associato va un passo oltre: dichiara una
AFRelationship(Spec: ISO 32000-2, §7.11.3ISO 32000-2 §7.11.3) — uno di otto valori standard (Source,Data,Alternative,Supplement,EncryptedPayload,FormData,Schema,Unspecified), o un valore personalizzato — che dice come il file si relaziona al contenuto a cui è allegato. - Quella relazione tipizzata è il meccanismo dietro le e-fatture ibride (ZUGFeRD / Factur-X) e gli allegati PDF/A-3 (Spec: ISO 19005-3, PDF/A-3ISO 19005-3 PDF/A-3).
- NextPDF supporta le primitive grezze del contenitore nel core:
embedFile()eembedFileFromString()con una relazione esplicita. Le edizioni Advanced aggiungono l’embedder dedicato per e-fatture EN 16931 / ZUGFeRD / Factur-X sopra queste primitive.
Come NextPDF lo affronta
Sezione intitolata “Come NextPDF lo affronta”Lo si pensi come due strati impilati uno sull’altro.
Lo strato inferiore è l’archiviazione. Un embedded file stream
(Spec: ISO 32000-2, §7.11.4ISO 32000-2 §7.11.4) è costituito dai byte del
file originale avvolti in un oggetto stream PDF, con un parameters dictionary
che registra la dimensione originale, la data di modifica e un checksum dei dati
non compressi. Lo stream è raggiunto attraverso un dizionario di file
specification il cui dizionario /EF punta all’embedded file stream — lo
stream stesso non porta /EF. Un lettore può estrarre di nuovo il file
byte-per-byte. Per rendere questi file individuabili, il document catalog
contiene un name tree EmbeddedFiles — una mappa ordinata da un nome a ciascuna
file specification — così che un lettore possa elencare «ecco i 3 file dentro
questo PDF» senza percorrere ogni pagina.
Lo strato superiore è il significato. Di per sé, un file incorporato è
semplicemente presente. Il meccanismo dei file associati
(Spec: ISO 32000-2, §14.13ISO 32000-2 §14.13) allega un file a qualcosa —
l’intero documento, una pagina, un oggetto grafico — e lo marca con una
AFRelationship. ISO 32000-2 definisce un piccolo vocabolario di otto valori
standard (Spec: ISO 32000-2, §7.11.3ISO 32000-2 §7.11.3), e permette anche
valori personalizzati; ciascun valore standard risponde a una domanda precisa:
AFRelationship | Cosa afferma riguardo al file |
|---|---|
Source | Questo è il materiale sorgente da cui è stato generato il contenuto visibile (per esempio, il documento originale di videoscrittura). |
Data | Questi sono dati strutturati legati al contenuto visibile — il caso canonico è l’XML della fattura dietro una pagina di fattura renderizzata. |
Alternative | Questa è una rappresentazione alternativa dello stesso contenuto (per esempio, una versione audio o video). |
Supplement | Questo è materiale supplementare che estende il contenuto ma non ne fa parte. |
EncryptedPayload | Il file incorporato è un payload cifrato che il PDF avvolge come un blob opaco. |
FormData | Il file è dati di modulo (FDF, XFDF, o un payload di modulo XML). |
Schema | Il file è uno schema che descrive la struttura di un file Data (per esempio, un XSD per dati XML o un JSON Schema). |
Unspecified | La relazione è deliberatamente non dichiarata. Onesto, ma non dice nulla a una macchina. |
Oltre a questi otto, lo standard permette anche valori di relazione personalizzati specifici dell’applicazione, così che il vocabolario sia estensibile anziché fisso.
Un file associato è definito da due cose che lavorano insieme, non da una sola
chiave. L’associazione /AF vincola la file specification a una parte del
documento; la chiave AFRelationship nella file specification poi dichiara la
relazione semantica. La voce /AF sul punto di associazione (il document
catalog, una pagina o un oggetto) è un array — quell’array contiene uno o
più dizionari di file specification, di solito come riferimenti indiretti; /AF
non è un singolo riferimento. Un file associato a livello di documento è la file
specification elencata nell’array /AF del document catalog, che porta la sua
AFRelationship. Si marchi quel foglio di calcolo Unspecified e lo si è
associato al documento ma non si è detto nulla a una macchina sul perché. Si
marchi lo stesso foglio di calcolo Data e si è detto a ogni lettore conforme
cos’è e a cosa serve. I byte sono gli stessi. La semantica no.
Per questo il caso della e-fattura non è «allegare un file XML». È «incorporare
questo XML come il file associato Data per questo documento, dentro un
contenitore PDF/A-3 conforme» — con la validità della fattura e l’accettazione
legale che restano controlli separati che il contenitore non esegue. Il flusso
ha quattro fasi, e l’ordine è ciò che lo mantiene corretto.
- Store the bytesThe file is wrapped in an embedded file stream with its size, dates, and a checksum (ISO 32000-2 §7.11.4).
- Register it by nameThe file specification is added to the EmbeddedFiles name tree so a reader can enumerate attachments without scanning the document.
- Declare the relationshipAn AFRelationship value (one of the eight standard values such as Source or Data) marks how the file relates to the content, associated at the document level (ISO 32000-2 §14.13.3).
- Make it archivalA PDF/A-3 carrier permits the embedded payload to ride inside one conforming archival PDF/A document; invoice validity and legal acceptance remain separate checks (ISO 19005-3).
Quella quarta fase è il motivo per cui PDF/A-3 esiste come profilo distinto. I
profili di archiviazione precedenti limitavano ciò che poteva essere
incorporato; PDF/A-3 (Spec: ISO 19005-3, PDF/A-3ISO 19005-3 PDF/A-3) è la
parte che permette a file di qualsiasi formato di viaggiare dentro un
documento di archiviazione conforme. Permette il payload incorporato — non
valida quel payload né conferisce uno stato legale. Senza di esso, la fattura
ibrida — un unico file che è sia la pagina che una persona legge sia i dati che
un sistema fiscale analizza — non potrebbe affatto essere un documento di
archiviazione PDF/A conforme; se la fattura sia valida e legalmente accettata
resta una questione separata. L’embedder dedicato per e-fatture che le edizioni
Advanced aggiungono è la cucitura di comodità esattamente su questo: incorpora
il payload, imposta la relazione su Data e lo registra correttamente, così che
non si debba assemblare a mano l’impiantistica del contenitore. La meccanica più
profonda di fatturazione e archiviazione vive sulle due pagine vicine collegate
qui sotto; questa pagina riguarda il contenitore su cui entrambe poggiano.
Esempio pratico
Sezione intitolata “Esempio pratico”Un programma piccolo e completo. Le due chiamate che contano sono la differenza
tra un file associato non tipizzato e uno tipizzato — e la relazione è un
argomento esplicito che si dovrebbe impostare. In questo motore, entrambe le
chiamate producono un file associato: embedFile() e embedFileFromString()
registrano sempre la file specification nell’array /AF del document catalog,
quindi l’unica cosa che la relazione cambia è cosa significa l’associazione. Il
valore predefinito è Unspecified, che associa il file ma non dice nulla a una
macchina sul perché; per il payload di una e-fattura lo si imposta su Data così
che un lettore possa trovarlo.
<?php
declare(strict_types=1);
use NextPDF\Core\Document;use NextPDF\Navigation\AFRelationship;
$document = Document::createStandalone();$document->addPage();$document->setFont('helvetica', 'B', 16);$document->cell(0, 12, 'Invoice INV-2026-0042', newLine: true);
// An UNTYPED associated file: the bytes are embedded AND the file spec is// added to the document catalog's /AF array, but the relationship says// nothing about why. A reader can open it; a machine cannot tell its role.// The relationship is left Unspecified (its default); the second argument is// the human-readable description. embedFile accepts the AFRelationship enum.$document->embedFile( '/srv/invoices/INV-2026-0042-source.docx', 'Original source document', AFRelationship::Unspecified,);
// A TYPED associated file: the invoice XML is declared as the DATA behind// the visible page. This is the relationship a hybrid e-invoice reader// looks for — the same intent the dedicated e-invoice embedder sets.// embedFileFromString takes the data, a filename, a description, and a// relationship as a PDF-name string ('/Data').$invoiceXml = $generateCiiXml(); // your ERP authors this; the engine never does$document->embedFileFromString( $invoiceXml, 'factur-x.xml', 'Factur-X invoice data', '/Data',);
$bytes = $document->getPdfData();La relazione '/Data' è inequivocabile. Il primo allegato — lasciato
Unspecified — è associato comunque, solo senza un significato dichiarato. Per
entrambe le chiamate il motore scrive l’embedded file stream, aggiunge il file
al name tree EmbeddedFiles, elenca la sua file specification nell’array /AF
del document catalog, e registra la relazione che si è dichiarato — non ne sceglie
una al posto dell’utente. Questo motore non ha una modalità solo-name-tree: ogni
file incorporato in questo modo è un file associato al documento, quindi la
relazione è l’unica leva che si controlla.
Equivoco comune
Sezione intitolata “Equivoco comune”Si dà spesso per scontato che «incorporato» e «associato» siano due parole per
la stessa cosa. Non lo sono. Incorporato riguarda l’archiviazione — i byte
sono dentro il PDF. Associato riguarda il vincolo — la file specification è
elencata in un array /AF su una parte del documento, e porta una
AFRelationship. Nel modello astratto del PDF un file può essere incorporato
nel name tree senza mai essere associato; il percorso embedFile() di NextPDF
non lo lascia lì — scrive sempre l’associazione /AF — quindi per questo motore
la domanda aperta non è mai se un file è associato ma cosa dice la relazione.
Una seconda trappola: presumere che un lettore «capirà» quale allegato è la
fattura. Un lettore conforme non dovrebbe indovinare. Cerca il file la cui
relazione dice Data. Si lasci la relazione Unspecified e si è associato il
payload pur non dicendo nulla di utile alla macchina sul suo ruolo.
Limiti e confini
Sezione intitolata “Limiti e confini”Il meccanismo del contenitore è potente in un modo su cui vale la pena essere
onesti: embedFile() legge qualunque percorso il processo PHP possa leggere.
Questa è la funzionalità — ed è anche il confine. Il motore allega i byte che
gli vengono dati; non decide, e non può decidere, per l’utente se un percorso
sia uno che si intendeva esporre.
| Edition | Availability |
|---|---|
| Core |
|
| Pro | Not in this edition |
| Enterprise | Not in this edition |
Due ulteriori limiti che vale la pena dichiarare chiaramente:
- Incorporare non è validare. Il motore porta i byte che gli si dà. Se l’XML incorporato sia un payload di fattura conforme è una questione separata, a cui risponde un validatore — si veda la pagina sulla fatturazione.
- Un allegato tipizzato non è di per sé un file di archiviazione conforme. Rendere il file ibrido un documento PDF/A-3 legale richiede la modalità di archiviazione e un controllo di conformità indipendente — si veda la pagina sull’archiviazione.
Documenti correlati
Sezione intitolata “Documenti correlati”- Fatture ed e-fatturazione — il caso
d’uso che questo meccanismo rende possibile: un PDF ibrido che porta una
fattura leggibile dalla macchina come suo file associato
Data. - Archiviazione e PDF/A — perché il contenitore è un file PDF/A-3 e cosa la conformità promette e cosa non promette.
- L’anatomia di un file PDF — dove si trovano il name tree e il document catalog nella struttura del file.
- Stream e filtri — come i byte di un file incorporato sono memorizzati e compressi dentro un oggetto stream.
Glossario
Sezione intitolata “Glossario”- Embedded file stream — un oggetto stream PDF che contiene i byte di un file esterno, con un parameters dictionary che registra la sua dimensione originale, le date e un checksum (ISO 32000-2 §7.11.4).
- EmbeddedFiles name tree — la mappa ordinata nel document catalog che elenca i file incorporati per nome, così che un lettore possa enumerare gli allegati senza scandire l’intero documento.
- File associato — un file incorporato vincolato a una parte del documento da
un’associazione
/AF(sul document catalog, una pagina o un oggetto) e che porta unaAFRelationshipche dichiara come si relaziona a quel contenuto; il caso a livello di documento — la file specification nell’array/AFdel catalog — è quello su cui questa pagina si concentra (ISO 32000-2 §14.13.3). - AFRelationship — la chiave della file specification il cui valore nomina la
relazione (ISO 32000-2 §7.11.3). Assume uno di otto valori standard (
Source,Data,Alternative,Supplement,EncryptedPayload,FormData,Schema,Unspecified) o un valore personalizzato;Dataè il valore che usa il payload di una e-fattura ibrida. - PDF/A-3 — il profilo di archiviazione ISO 19005-3 che permette di incorporare file di qualsiasi formato, abilitando un documento ibrido conforme.
- Fattura ibrida — un unico file PDF che è sia una pagina leggibile dall’uomo sia un payload di fattura incorporato leggibile dalla macchina.