PDF adalah sebuah wadah: berkas tertanam dan data terasosiasi
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
Sekilas
Bagian berjudul “Sekilas”Kebanyakan orang membayangkan PDF sebagai tumpukan halaman. Itu bagian yang Anda lihat. Tetapi PDF juga adalah sebuah wadah, dan ia dapat membawa berkas-berkas lain secara utuh di dalamnya — sebuah spreadsheet, sebuah payload XML, dokumen sumber aslinya — dibundel ke dalam satu berkas tunggal yang sama yang Anda serahkan kepada orang lain.
Halaman ini menjelaskan bagaimana itu bekerja: embedded-file stream yang menyimpan byte-nya, name tree yang mendaftarnya, dan satu kunci yang memutuskan apakah sebuah lampiran hanya sekadar ada di situ atau benar-benar bermakna sesuatu.
Mengapa ini penting
Bagian berjudul “Mengapa ini penting”Sebuah lampiran tak bertipe dan lampiran bertipe terlihat identik bagi manusia. Keduanya adalah berkas yang menumpang di dalam PDF, dan — pada mesin ini — keduanya terasosiasi dengan dokumen. Bedanya adalah salah satunya memberi tahu mesin untuk apa ia ada, sedangkan yang lain membiarkan relasinya kosong untuk ditebak mesin.
Perbedaan itu adalah segalanya bagi sebuah e-invoice hibrida. Sebuah platform pajak tidak membaca halaman faktur Anda; ia membaca XML yang Anda tanamkan. Jika XML itu dilampirkan sebagai gumpalan tak terbedakan alih-alih sebagai data faktur untuk dokumen yang terlihat, sebuah pembaca yang sesuai tidak punya cara yang andal untuk tahu bahwa itu adalah payload yang harus diproses. Halamannya terlihat sempurna. Fakturnya ditolak. Kegagalan itu datang beberapa hari kemudian, dengan sebuah pembayaran yang tertahan di belakangnya.
Membuat relasinya benar, di lapisan yang menghasilkan berkas, jauh lebih murah daripada menemukannya satu faktur yang ditolak pada satu waktu.
Versi singkat
Bagian berjudul “Versi singkat”- Sebuah PDF dapat menanamkan byte berkas apa pun sebagai embedded file stream (Spec: ISO 32000-2, §7.11.4ISO 32000-2 §7.11.4). Stream itu membawa datanya ditambah sebuah parameters dictionary kecil: ukuran asli, tanggal, dan sebuah checksum.
- Berkas tertanam dikatalogkan dalam
EmbeddedFilesname tree, sehingga sebuah pembaca dapat mengenumerasinya berdasarkan nama tanpa memindai seluruh dokumen. - Sebuah associated file melangkah satu langkah lebih jauh: ia mendeklarasikan
sebuah
AFRelationship(Spec: ISO 32000-2, §7.11.3ISO 32000-2 §7.11.3) — salah satu dari delapan nilai standar (Source,Data,Alternative,Supplement,EncryptedPayload,FormData,Schema,Unspecified), atau sebuah nilai kustom — yang menyatakan bagaimana berkas itu berhubungan dengan konten tempat ia dilampirkan. - Relasi bertipe itu adalah mekanisme di balik e-invoice hibrida (ZUGFeRD / Factur-X) dan lampiran PDF/A-3 (Spec: ISO 19005-3, PDF/A-3ISO 19005-3 PDF/A-3).
- NextPDF mendukung primitif wadah mentah di inti:
embedFile()danembedFileFromString()dengan sebuah relasi eksplisit. Edisi Advanced menambahkan embedder e-invoice EN 16931 / ZUGFeRD / Factur-X khusus di atas primitif-primitif ini.
Bagaimana NextPDF menanganinya
Bagian berjudul “Bagaimana NextPDF menanganinya”Anggaplah ini sebagai dua lapisan yang ditumpuk satu di atas yang lain.
Lapisan bawah adalah penyimpanan. Sebuah embedded file stream
(Spec: ISO 32000-2, §7.11.4ISO 32000-2 §7.11.4) adalah byte berkas asli yang
dibungkus dalam sebuah objek stream PDF, dengan sebuah parameters dictionary yang
mencatat ukuran asli, tanggal modifikasi, dan sebuah checksum dari data yang tidak
terkompresi. Stream itu dijangkau melalui sebuah file specification dictionary yang
/EF dictionary-nya menunjuk ke embedded file stream — stream itu sendiri tidak
membawa /EF. Sebuah pembaca dapat menarik kembali berkas itu byte demi byte. Agar
berkas-berkas ini dapat ditemukan, document catalog menyimpan sebuah
EmbeddedFiles name tree — sebuah peta terurut dari sebuah nama ke setiap file
specification — sehingga sebuah penampil dapat mendaftar “ini ada 3 berkas di dalam
PDF ini” tanpa menelusuri setiap halaman.
Lapisan atas adalah makna. Dengan sendirinya, sebuah berkas tertanam hanya
sekadar hadir. Mekanisme associated-files (Spec: ISO 32000-2, §14.13ISO 32000-2 §14.13)
melampirkan sebuah berkas ke sesuatu — seluruh dokumen, sebuah halaman, sebuah objek
grafis — dan menstempelnya dengan sebuah AFRelationship. ISO 32000-2 mendefinisikan
sebuah kosakata kecil berisi delapan nilai standar (Spec: ISO 32000-2, §7.11.3ISO 32000-2 §7.11.3),
dan mengizinkan nilai kustom juga; setiap nilai standar menjawab sebuah pertanyaan
yang presisi:
AFRelationship | Apa yang ia tegaskan tentang berkas |
|---|---|
Source | Ini adalah materi sumber yang darinyalah konten yang terlihat dihasilkan (misalnya, dokumen word-processor aslinya). |
Data | Ini adalah data terstruktur yang terikat pada konten yang terlihat — kasus kanonisnya adalah XML faktur di balik halaman faktur yang dirender. |
Alternative | Ini adalah representasi alternatif dari konten yang sama (misalnya, sebuah versi audio atau video). |
Supplement | Ini adalah materi pelengkap yang memperluas konten tetapi bukan bagian darinya. |
EncryptedPayload | Berkas tertanam adalah sebuah payload terenkripsi yang dibungkus PDF sebagai gumpalan buram. |
FormData | Berkas adalah data formulir (FDF, XFDF, atau sebuah payload formulir XML). |
Schema | Berkas adalah sebuah skema yang menggambarkan struktur dari sebuah berkas Data (misalnya, sebuah XSD untuk data XML atau sebuah JSON Schema). |
Unspecified | Relasi sengaja tidak dinyatakan. Jujur, tetapi ia tidak memberi tahu mesin apa pun. |
Di luar kedelapan nilai ini, standar juga mengizinkan nilai relasi kustom yang spesifik untuk aplikasi, sehingga kosakatanya dapat diperluas alih-alih tetap.
Sebuah associated file didefinisikan oleh dua hal yang bekerja bersama, bukan satu
kunci saja. Asosiasi /AF mengikat file specification ke sebuah bagian dokumen;
kunci AFRelationship dalam file specification kemudian menyatakan relasi
semantiknya. Entri /AF pada titik asosiasi (document catalog, sebuah halaman, atau
sebuah objek) adalah sebuah larik — larik itu memuat satu atau lebih file
specification dictionary, biasanya sebagai referensi tidak langsung; /AF bukan sebuah
referensi tunggal. Sebuah associated file tingkat-dokumen adalah file specification yang
tercantum dalam larik /AF document catalog, yang membawa AFRelationship-nya. Tandai
spreadsheet itu Unspecified dan Anda telah mengasosiasikannya dengan dokumen tetapi
tidak memberi tahu mesin apa pun tentang mengapa. Tandai spreadsheet yang sama dengan
Data dan Anda telah memberi tahu setiap pembaca yang sesuai apa ia dan untuk apa ia.
Byte-nya sama. Semantiknya tidak.
Inilah sebabnya kasus e-invoice bukanlah “lampirkan sebuah berkas XML”. Ia adalah
“tanamkan XML ini sebagai associated file Data untuk dokumen ini, di dalam sebuah
pembawa PDF/A-3 yang sesuai” — dengan validitas faktur dan penerimaan hukum tetap
menjadi pemeriksaan terpisah yang tidak dilakukan pembawanya. Alurnya memiliki empat
tahap, dan urutannyalah yang menjaga semuanya tetap benar.
- 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).
Tahap keempat itulah sebabnya PDF/A-3 ada sebagai profil tersendiri. Profil arsip
sebelumnya membatasi apa yang dapat ditanamkan; PDF/A-3
(Spec: ISO 19005-3, PDF/A-3ISO 19005-3 PDF/A-3) adalah bagian yang mengizinkan
berkas dengan format apa pun untuk menumpang di dalam sebuah dokumen arsip yang
sesuai. Ia mengizinkan payload tertanam — ia tidak memvalidasi payload itu atau
memberikan status hukum. Tanpanya, faktur hibrida — satu berkas yang sekaligus
merupakan halaman yang dibaca seseorang dan data yang diuraikan sistem pajak — tidak
akan bisa menjadi sebuah dokumen arsip PDF/A yang sesuai sama sekali; apakah faktur itu
valid dan secara hukum diterima tetap merupakan pertanyaan terpisah. Embedder
e-invoice khusus yang ditambahkan edisi Advanced adalah jahitan kenyamanan tepat di
atas hal ini: ia menanamkan payload, menyetel relasi ke Data, dan mendaftarkannya
dengan benar, sehingga Anda tidak perlu merakit pipa wadahnya dengan tangan. Mekanika
fakturasi dan pengarsipan yang lebih dalam ada pada dua halaman tetangga yang ditautkan
di bawah; halaman ini adalah tentang wadah yang menjadi pijakan keduanya.
Contoh praktis
Bagian berjudul “Contoh praktis”Sebuah program kecil dan lengkap. Dua panggilan yang penting adalah pembeda antara
associated file tak bertipe dan yang bertipe — dan relasinya adalah sebuah argumen
eksplisit yang sebaiknya Anda setel. Pada mesin ini, kedua panggilan menghasilkan
sebuah associated file: embedFile() dan embedFileFromString() selalu mendaftarkan
file specification dalam larik /AF document catalog, sehingga satu-satunya hal yang
diubah relasi adalah apa arti asosiasi itu. Ia berdefault ke Unspecified, yang
mengasosiasikan berkas tetapi tidak memberi tahu mesin apa pun tentang mengapa; untuk
sebuah payload e-invoice Anda menyetelnya ke Data agar sebuah pembaca dapat
menemukannya.
<?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();Relasi '/Data' tidak dapat disalahartikan. Lampiran pertama — yang dibiarkan
Unspecified — tetap terasosiasi, hanya tanpa makna yang dinyatakan. Untuk kedua
panggilan, mesin menulis embedded file stream, menambahkan berkas ke EmbeddedFiles
name tree, mencantumkan file specification-nya dalam larik /AF document catalog, dan
mencatat relasi yang Anda nyatakan — ia tidak memilihkannya untuk Anda. Mesin ini tidak
memiliki mode name-tree-only: setiap berkas yang Anda tanamkan dengan cara ini adalah
associated file tingkat-dokumen, sehingga relasi adalah satu-satunya tuas yang Anda
kendalikan.
Kesalahpahaman umum
Bagian berjudul “Kesalahpahaman umum”Asumsi yang sering muncul adalah bahwa “embedded” dan “associated” adalah dua kata untuk
hal yang sama. Mereka bukan. Embedded adalah tentang penyimpanan — byte-nya berada di
dalam PDF. Associated adalah tentang pengikatan — file specification tercantum dalam
sebuah larik /AF pada sebuah bagian dokumen, dan ia membawa sebuah AFRelationship.
Dalam model PDF abstrak, sebuah berkas dapat ditanamkan ke dalam name tree tanpa pernah
terasosiasi; jalur embedFile() NextPDF tidak meninggalkannya begitu saja — ia selalu
menulis asosiasi /AF — sehingga untuk mesin ini, pertanyaan terbukanya tidak pernah
apakah sebuah berkas terasosiasi melainkan apa yang dinyatakan relasinya.
Jebakan kedua: mengasumsikan sebuah penampil akan “mencari tahu” lampiran mana yang
merupakan fakturnya. Sebuah pembaca yang sesuai tidak seharusnya menebak. Ia mencari
berkas yang relasinya menyatakan Data. Biarkan relasinya Unspecified dan Anda telah
mengasosiasikan payload itu sambil tidak memberi tahu mesin apa pun yang berguna tentang
perannya.
Batasan dan ruang lingkup
Bagian berjudul “Batasan dan ruang lingkup”Mekanisme wadah ini kuat dengan cara yang layak untuk dikatakan secara jujur:
embedFile() membaca path apa pun yang dapat dibaca oleh proses PHP. Itu adalah
fiturnya — dan itu juga batasnya. Mesin melampirkan byte yang diberikan kepadanya; ia
tidak, dan tidak dapat, memutuskan untuk Anda apakah sebuah path adalah path yang
Anda maksudkan untuk diekspos.
| Edition | Availability |
|---|---|
| Core |
|
| Pro | Not in this edition |
| Enterprise | Not in this edition |
Dua batas lagi yang layak dinyatakan secara terus terang:
- Menanamkan bukan memvalidasi. Mesin membawa byte yang Anda berikan kepadanya. Apakah XML tertanam itu adalah payload faktur yang sesuai adalah pertanyaan terpisah, yang dijawab oleh sebuah validator — lihat halaman fakturasi.
- Sebuah lampiran bertipe bukanlah berkas arsip yang sesuai dengan sendirinya. Menjadikan berkas hibrida itu sebuah dokumen PDF/A-3 yang legal memerlukan mode arsip dan sebuah pemeriksaan kesesuaian yang independen — lihat halaman pengarsipan.
Dokumen terkait
Bagian berjudul “Dokumen terkait”- Invoices and e-invoicing — kasus
penggunaan yang dimungkinkan mekanisme ini: sebuah PDF hibrida yang membawa sebuah
faktur yang dapat dibaca mesin sebagai associated file
Data-nya. - Archival and PDF/A — mengapa pembawanya adalah berkas PDF/A-3 dan apa yang dijanjikan maupun tidak dijanjikan oleh kesesuaian.
- The anatomy of a PDF file — di mana name tree dan document catalog berada dalam struktur berkas.
- Streams and filters — bagaimana byte sebuah berkas tertanam disimpan dan dikompresi di dalam sebuah objek stream.
Glosarium
Bagian berjudul “Glosarium”- Embedded file stream — sebuah objek stream PDF yang menampung byte dari sebuah berkas eksternal, dengan sebuah parameters dictionary yang mencatat ukuran asli, tanggal, dan sebuah checksum (ISO 32000-2 §7.11.4).
- EmbeddedFiles name tree — peta terurut dalam document catalog yang mendaftarkan berkas tertanam berdasarkan nama, sehingga sebuah pembaca dapat mengenumerasi lampiran tanpa memindai seluruh dokumen.
- Associated file — sebuah berkas tertanam yang terikat ke sebuah bagian dokumen
oleh asosiasi
/AF(pada document catalog, sebuah halaman, atau sebuah objek) dan membawa sebuahAFRelationshipyang menyatakan bagaimana ia berhubungan dengan konten itu; kasus tingkat-dokumen — file specification dalam larik/AFkatalog — adalah yang menjadi pusat halaman ini (ISO 32000-2 §14.13.3). - AFRelationship — kunci file-specification yang nilainya menamai relasi
(ISO 32000-2 §7.11.3). Ia mengambil salah satu dari delapan nilai standar
(
Source,Data,Alternative,Supplement,EncryptedPayload,FormData,Schema,Unspecified) atau sebuah nilai kustom;Dataadalah nilai yang dipakai sebuah payload e-invoice hibrida. - PDF/A-3 — profil arsip ISO 19005-3 yang mengizinkan berkas dengan format apa pun untuk ditanamkan, memungkinkan sebuah dokumen hibrida yang sesuai.
- Hybrid invoice — satu berkas PDF yang sekaligus merupakan halaman yang dapat dibaca manusia dan sebuah payload faktur tertanam yang dapat dibaca mesin.