PDF คือคอนเทนเนอร์: ไฟล์ฝังตัวและข้อมูลที่เชื่อมโยง
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
ภาพรวมโดยสังเขป
หัวข้อที่มีชื่อว่า “ภาพรวมโดยสังเขป”คนส่วนใหญ่นึกภาพ PDF เป็นกองหน้ากระดาษ นั่นคือส่วนที่คุณมองเห็น แต่ PDF ก็เป็นคอนเทนเนอร์ด้วย และสามารถบรรจุไฟล์อื่นทั้งไฟล์ไว้ภายในได้ — สเปรดชีต เพย์โหลด XML เอกสารต้นฉบับ — รวมเข้าไว้ในไฟล์เดียวกันที่คุณส่งต่อให้คนอื่น
หน้านี้อธิบายว่าสิ่งนั้นทำงานอย่างไร: embedded-file stream ที่จัดเก็บไบต์ name tree ที่แสดงรายการไฟล์เหล่านั้น และคีย์เดียวที่ตัดสินว่าไฟล์แนบเป็นเพียงสิ่งที่อยู่ตรงนั้นเฉยๆ หรือมีความหมายจริงๆ
เหตุใดเรื่องนี้จึงสำคัญ
หัวข้อที่มีชื่อว่า “เหตุใดเรื่องนี้จึงสำคัญ”ไฟล์แนบแบบ ไม่ระบุชนิด กับแบบ ระบุชนิด ดูเหมือนกันสำหรับมนุษย์ ทั้งคู่เป็นไฟล์ที่อยู่ภายใน PDF และ — ในเอนจินนี้ — ทั้งคู่เชื่อมโยงกับเอกสาร ความแตกต่างคือไฟล์หนึ่งบอกเครื่องจักรว่ามันมีไว้เพื่ออะไร ส่วนอีกไฟล์ทิ้งความสัมพันธ์ไว้ว่างเปล่าให้เครื่องจักรเดาเอง
ความแตกต่างนั้นคือทุกอย่างสำหรับ e-invoice แบบไฮบริด แพลตฟอร์มภาษีไม่ได้อ่านหน้าใบแจ้งหนี้ของคุณ มันอ่าน XML ที่คุณฝังไว้ หาก XML นั้นถูกแนบมาเป็นก้อนข้อมูลที่ไม่ได้จำแนกไว้แทนที่จะเป็น ข้อมูล ของใบแจ้งหนี้สำหรับเอกสารที่มองเห็น โปรแกรมอ่านที่สอดคล้องกับมาตรฐานก็ไม่มีทางที่เชื่อถือได้ที่จะรู้ว่ามันคือเพย์โหลดที่ต้องประมวลผล หน้าดูสมบูรณ์แบบ ใบแจ้งหนี้ถูกปฏิเสธ ความล้มเหลวมาถึงในอีกหลายวันต่อมา พร้อมกับการชำระเงินที่ถูกระงับอยู่เบื้องหลัง
การระบุความสัมพันธ์ให้ถูกต้องในชั้นที่ผลิตไฟล์นั้นถูกกว่าการค้นพบทีละหนึ่งใบแจ้งหนี้ที่ถูกปฏิเสธมาก
ฉบับย่อ
หัวข้อที่มีชื่อว่า “ฉบับย่อ”- PDF สามารถ ฝังไบต์ของไฟล์ใดก็ได้ ในรูปของ embedded file stream (Spec: ISO 32000-2, §7.11.4ISO 32000-2 §7.11.4) สตรีมบรรจุข้อมูลพร้อมกับ parameters dictionary ขนาดเล็ก: ขนาดเดิม วันที่ และ checksum
- ไฟล์ฝังตัวถูกจัดทำรายการไว้ใน
EmbeddedFilesname tree เพื่อให้โปรแกรมอ่านสามารถระบุไฟล์เหล่านั้นตามชื่อได้โดยไม่ต้องสแกนทั้งเอกสาร - ไฟล์ที่เชื่อมโยง ไปไกลกว่านั้นอีกขั้น: มันประกาศ
AFRelationship(Spec: ISO 32000-2, §7.11.3ISO 32000-2 §7.11.3) — หนึ่งในแปดค่ามาตรฐาน (Source,Data,Alternative,Supplement,EncryptedPayload,FormData,Schema,Unspecified) หรือค่ากำหนดเอง — บอกว่าไฟล์นั้นเกี่ยวข้อง อย่างไร กับเนื้อหาที่มันถูกแนบไว้ - ความสัมพันธ์ที่ระบุชนิดนั้นคือกลไกเบื้องหลัง e-invoice แบบไฮบริด (ZUGFeRD / Factur-X) และไฟล์แนบ PDF/A-3 (Spec: ISO 19005-3, PDF/A-3ISO 19005-3 PDF/A-3)
- NextPDF รองรับ container primitive ดิบในคอร์:
embedFile()และembedFileFromString()พร้อมความสัมพันธ์ที่ระบุชัดเจน เอดิชัน Advanced เพิ่ม ตัวฝัง e-invoice เฉพาะของ EN 16931 / ZUGFeRD / Factur-X ขึ้นบน primitive เหล่านี้
NextPDF จัดการเรื่องนี้อย่างไร
หัวข้อที่มีชื่อว่า “NextPDF จัดการเรื่องนี้อย่างไร”ลองนึกว่ามันเป็นสองชั้นซ้อนทับกัน
ชั้นล่าง คือการจัดเก็บ embedded file stream (Spec: ISO 32000-2, §7.11.4ISO 32000-2 §7.11.4) คือไบต์ของไฟล์ต้นฉบับที่ห่อหุ้มไว้ในอ็อบเจกต์สตรีมของ PDF พร้อม parameters dictionary ที่บันทึกขนาดเดิม วันที่แก้ไข และ checksum ของข้อมูลที่ไม่บีบอัด สตรีมถูกเข้าถึงผ่าน dictionary แบบ file specification ที่มี dictionary /EF ชี้ไปยัง embedded file stream — ตัวสตรีมเองไม่ได้บรรจุ /EF โปรแกรมอ่านสามารถดึงไฟล์กลับออกมาแบบไบต์ต่อไบต์ได้ เพื่อให้ค้นหาไฟล์เหล่านี้ได้ document catalog เก็บ EmbeddedFiles name tree — แผนที่ที่เรียงลำดับจากชื่อไปยังแต่ละ file specification — เพื่อให้โปรแกรมอ่านแสดงรายการ “นี่คือ 3 ไฟล์ภายใน PDF นี้” ได้โดยไม่ต้องเดินดูทุกหน้า
ชั้นบน คือความหมาย ในตัวมันเอง ไฟล์ฝังตัวเป็นเพียงสิ่งที่มีอยู่ กลไกไฟล์ที่เชื่อมโยง (Spec: ISO 32000-2, §14.13ISO 32000-2 §14.13) แนบไฟล์เข้ากับบางสิ่ง — ทั้งเอกสาร หน้าหนึ่ง อ็อบเจกต์กราฟิก — และประทับมันด้วย AFRelationship ISO 32000-2 นิยามชุดคำศัพท์ขนาดเล็กของแปดค่ามาตรฐาน (Spec: ISO 32000-2, §7.11.3ISO 32000-2 §7.11.3) และอนุญาตให้มีค่ากำหนดเองด้วย แต่ละค่ามาตรฐานตอบคำถามที่ชัดเจน:
AFRelationship | สิ่งที่มันยืนยันเกี่ยวกับไฟล์ |
|---|---|
Source | นี่คือวัสดุต้นทางที่เนื้อหาที่มองเห็นถูกสร้างขึ้น จาก (ตัวอย่างเช่น เอกสารโปรแกรมประมวลผลคำต้นฉบับ) |
Data | นี่คือข้อมูลที่มีโครงสร้างซึ่งผูกอยู่กับเนื้อหาที่มองเห็น — กรณีตามแบบฉบับคือ XML ใบแจ้งหนี้ที่อยู่เบื้องหลังหน้าใบแจ้งหนี้ที่เรนเดอร์แล้ว |
Alternative | นี่คือการแสดงผลทางเลือกของเนื้อหาเดียวกัน (ตัวอย่างเช่น เวอร์ชันเสียงหรือวิดีโอ) |
Supplement | นี่คือวัสดุเสริมที่ขยายเนื้อหาแต่ไม่ใช่ส่วนหนึ่งของเนื้อหา |
EncryptedPayload | ไฟล์ฝังตัวคือเพย์โหลดที่เข้ารหัสลับซึ่ง PDF ห่อหุ้มไว้เป็นก้อนข้อมูลทึบ |
FormData | ไฟล์คือข้อมูลฟอร์ม (FDF, XFDF หรือเพย์โหลดฟอร์ม XML) |
Schema | ไฟล์คือสคีมาที่อธิบายโครงสร้างของไฟล์ Data (ตัวอย่างเช่น XSD สำหรับข้อมูล XML หรือ JSON Schema) |
Unspecified | ความสัมพันธ์ถูกไม่ระบุไว้โดยตั้งใจ ซื่อสัตย์ แต่ก็ไม่ได้บอกอะไรกับเครื่องจักรเลย |
นอกเหนือจากแปดค่านี้ มาตรฐานยังอนุญาตค่าความสัมพันธ์กำหนดเองที่เฉพาะกับแอปพลิเคชันด้วย ดังนั้นชุดคำศัพท์จึงขยายได้แทนที่จะตายตัว
ไฟล์ที่เชื่อมโยงถูกนิยามด้วยสองสิ่งที่ทำงานร่วมกัน ไม่ใช่ด้วยคีย์เดียวเพียงลำพัง การเชื่อมโยง /AF ผูก file specification เข้ากับส่วนหนึ่งของเอกสาร จากนั้นคีย์ AFRelationship ใน file specification จึง ระบุความสัมพันธ์เชิงความหมาย รายการ /AF บนจุดเชื่อมโยง (document catalog หน้าหนึ่ง หรืออ็อบเจกต์) เป็น อาร์เรย์ — อาร์เรย์นั้นบรรจุ file specification dictionary หนึ่งตัวหรือมากกว่า โดยปกติเป็น indirect reference; /AF ไม่ใช่ reference เดี่ยว ไฟล์ที่เชื่อมโยงระดับเอกสารคือ file specification ที่แสดงอยู่ในอาร์เรย์ /AF ของ document catalog โดยบรรจุ AFRelationship ของมัน กำกับสเปรดชีตนั้นว่า Unspecified แล้วคุณก็ได้เชื่อมโยงมันกับเอกสารแต่ไม่ได้บอกเครื่องจักรเลยว่า ทำไม กำกับสเปรดชีตเดียวกันนั้นว่า Data แล้วคุณก็ได้บอกโปรแกรมอ่านที่สอดคล้องกับมาตรฐานทุกตัวว่ามันคืออะไรและมีไว้เพื่ออะไร ไบต์เหมือนกัน ความหมายไม่เหมือน
นี่คือเหตุผลที่กรณี e-invoice ไม่ใช่ “แนบไฟล์ XML” แต่เป็น “ฝัง XML นี้ในฐานะไฟล์ที่เชื่อมโยงแบบ Data สำหรับเอกสารนี้ ภายในตัวพา PDF/A-3 ที่สอดคล้องกับมาตรฐาน” — โดยความถูกต้องของใบแจ้งหนี้และการยอมรับทางกฎหมายยังคงเป็นการตรวจสอบที่แยกต่างหากซึ่งตัวพาไม่ได้ดำเนินการ ขั้นตอนมีสี่ระยะ และลำดับคือสิ่งที่ทำให้มันถูกต้อง
- 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).
ระยะที่สี่นั้นคือเหตุผลที่ PDF/A-3 มีอยู่ในฐานะโปรไฟล์ที่แตกต่าง โปรไฟล์การเก็บถาวรรุ่นก่อนๆจำกัดสิ่งที่ฝังได้ PDF/A-3 (Spec: ISO 19005-3, PDF/A-3ISO 19005-3 PDF/A-3) คือส่วนที่อนุญาตให้ไฟล์รูปแบบ ใดก็ได้ อยู่ภายในเอกสารการเก็บถาวรที่สอดคล้องกับมาตรฐาน มันอนุญาตเพย์โหลดที่ฝังไว้ — มันไม่ได้ตรวจสอบเพย์โหลดนั้นหรือมอบสถานะทางกฎหมายให้ หากไม่มีมัน ใบแจ้งหนี้แบบไฮบริด — ไฟล์เดียวที่เป็นทั้งหน้าที่คนอ่านและข้อมูลที่ระบบภาษีแจงรูป — ก็ไม่อาจเป็นเอกสาร PDF/A สำหรับการเก็บถาวรที่สอดคล้องกับมาตรฐานได้เลย ส่วนว่าใบแจ้งหนี้ ถูกต้อง และได้รับการ ยอมรับ ทางกฎหมายหรือไม่ ยังคงเป็นคำถามที่แยกต่างหาก ตัวฝัง e-invoice เฉพาะที่ เอดิชัน Advanced เพิ่ม คือรอยต่อแห่งความสะดวกที่อยู่เหนือสิ่งนี้พอดี: มันฝังเพย์โหลด ตั้งความสัมพันธ์เป็น Data และลงทะเบียนอย่างถูกต้อง เพื่อที่คุณจะไม่ต้องประกอบท่อร้อยสายคอนเทนเนอร์ด้วยมือ กลไกการออกใบแจ้งหนี้และการเก็บถาวรที่ลึกกว่าอยู่ในสองหน้าข้างเคียงที่ลิงก์ไว้ด้านล่าง หน้านี้ว่าด้วยคอนเทนเนอร์ที่ทั้งสองหน้านั้นยืนอยู่บน
ตัวอย่างเชิงปฏิบัติ
หัวข้อที่มีชื่อว่า “ตัวอย่างเชิงปฏิบัติ”โปรแกรมเล็กๆที่สมบูรณ์ การเรียกสองครั้งที่สำคัญคือความแตกต่างระหว่างไฟล์ที่เชื่อมโยงแบบ ไม่ระบุชนิด กับแบบ ระบุชนิด — และความสัมพันธ์เป็นอาร์กิวเมนต์ที่ชัดเจนซึ่งคุณควรตั้งค่า ในเอนจินนี้ การเรียก ทั้งสอง ครั้งผลิตไฟล์ที่เชื่อมโยง: embedFile() และ embedFileFromString() ลงทะเบียน file specification ในอาร์เรย์ /AF ของ document catalog เสมอ ดังนั้นสิ่งเดียวที่ความสัมพันธ์เปลี่ยนคือ การเชื่อมโยงนั้นหมายถึงอะไร มันมีค่าเริ่มต้นเป็น Unspecified ซึ่งเชื่อมโยงไฟล์แต่ไม่ได้บอกเครื่องจักรเลยว่าทำไม สำหรับเพย์โหลด e-invoice คุณตั้งค่าเป็น Data เพื่อให้โปรแกรมอ่านค้นหามันได้
<?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();ความสัมพันธ์ '/Data' นั้นชัดเจนไม่กำกวม ไฟล์แนบแรก — ที่ปล่อยไว้เป็น Unspecified — ก็ถูกเชื่อมโยงเช่นกัน เพียงแต่ไม่มีความหมายที่ระบุไว้ สำหรับการเรียกทั้งสองครั้ง เอนจินเขียน embedded file stream เพิ่มไฟล์ลงใน EmbeddedFiles name tree แสดงรายการ file specification ของมันในอาร์เรย์ /AF ของ document catalog และบันทึกความสัมพันธ์ที่คุณระบุ — มันไม่ได้เลือกให้คุณ เอนจินนี้ไม่มีโหมดที่มีเฉพาะ name tree: ทุกไฟล์ที่คุณฝังด้วยวิธีนี้คือไฟล์ที่เชื่อมโยงกับเอกสาร ดังนั้นความสัมพันธ์จึงเป็นคันโยกเดียวที่คุณควบคุม
ความเข้าใจผิดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ความเข้าใจผิดที่พบบ่อย”ข้อสันนิษฐานที่พบบ่อยคือ “embedded” และ “associated” เป็นสองคำสำหรับสิ่งเดียวกัน มันไม่ใช่ Embedded ว่าด้วยการจัดเก็บ — ไบต์อยู่ภายใน PDF Associated ว่าด้วยการผูก — file specification ถูกแสดงรายการในอาร์เรย์ /AF บนส่วนหนึ่งของเอกสาร และมันบรรจุ AFRelationship ในโมเดล PDF เชิงนามธรรม ไฟล์สามารถถูกฝังลงใน name tree ได้โดยไม่เคยถูกเชื่อมโยงเลย เส้นทาง embedFile() ของ NextPDF ไม่ได้ปล่อยมันไว้เช่นนั้น — มันเขียนการเชื่อมโยง /AF เสมอ — ดังนั้นสำหรับเอนจินนี้ คำถามที่ค้างคาไม่เคยเป็นว่าไฟล์ถูกเชื่อมโยงหรือ ไม่ แต่เป็นว่าความสัมพันธ์ บอกอะไร
กับดักข้อที่สอง: การสันนิษฐานว่าโปรแกรมอ่านจะ “คิดเอาเอง” ว่าไฟล์แนบไหนคือใบแจ้งหนี้ โปรแกรมอ่านที่สอดคล้องกับมาตรฐานไม่ควรเดา มันมองหาไฟล์ที่ความสัมพันธ์ระบุว่า Data ปล่อยความสัมพันธ์ไว้เป็น Unspecified แล้วคุณก็ได้เชื่อมโยงเพย์โหลดในขณะที่ไม่ได้บอกเครื่องจักรอะไรที่เป็นประโยชน์เกี่ยวกับบทบาทของมันเลย
ขีดจำกัดและขอบเขต
หัวข้อที่มีชื่อว่า “ขีดจำกัดและขอบเขต”กลไกคอนเทนเนอร์ทรงพลังในแบบที่ควรพูดอย่างซื่อสัตย์: embedFile() อ่าน path ใดก็ตามที่กระบวนการ PHP อ่านได้ นั่นคือคุณสมบัติ — และก็เป็นขอบเขตด้วย เอนจินแนบไบต์ที่มันได้รับ มันไม่ได้และไม่อาจตัดสินใจแทนคุณว่า path หนึ่งเป็น path ที่คุณ ตั้งใจ จะเปิดเผยหรือไม่
| Edition | Availability |
|---|---|
| Core |
|
| Pro | Not in this edition |
| Enterprise | Not in this edition |
ขีดจำกัดอีกสองข้อที่ควรกล่าวอย่างตรงไปตรงมา:
- การฝังไม่ใช่การตรวจสอบ เอนจินพาไบต์ที่คุณให้มันไป ส่วนว่า XML ที่ฝังไว้เป็นเพย์โหลดใบแจ้งหนี้ที่ สอดคล้องกับมาตรฐาน หรือไม่ เป็นคำถามที่แยกต่างหาก ซึ่งตอบโดยตัวตรวจสอบ — ดูหน้าการออกใบแจ้งหนี้
- ไฟล์แนบที่ระบุชนิดไม่ใช่ไฟล์การเก็บถาวรที่สอดคล้องกับมาตรฐานในตัวมันเอง การทำให้ไฟล์ไฮบริดเป็นเอกสาร PDF/A-3 ที่ถูกต้องตามกฎหมายต้องใช้โหมดการเก็บถาวรและการตรวจสอบความสอดคล้องที่เป็นอิสระ — ดูหน้าการเก็บถาวร
เอกสารที่เกี่ยวข้อง
หัวข้อที่มีชื่อว่า “เอกสารที่เกี่ยวข้อง”- ใบแจ้งหนี้และ e-invoicing — กรณีการใช้งานที่กลไกนี้ทำให้เป็นไปได้: PDF แบบไฮบริดที่บรรจุใบแจ้งหนี้ที่เครื่องอ่านได้ในฐานะไฟล์ที่เชื่อมโยงแบบ
Data - การเก็บถาวรและ PDF/A — เหตุใดตัวพาจึงเป็นไฟล์ PDF/A-3 และความสอดคล้องสัญญาและไม่สัญญาอะไรบ้าง
- กายวิภาคของไฟล์ PDF — ตำแหน่งที่ name tree และ document catalog ตั้งอยู่ในโครงสร้างของไฟล์
- สตรีมและฟิลเตอร์ — วิธีที่ไบต์ของไฟล์ฝังตัวถูกจัดเก็บและบีบอัดภายในอ็อบเจกต์สตรีม
อภิธานศัพท์
หัวข้อที่มีชื่อว่า “อภิธานศัพท์”- Embedded file stream — อ็อบเจกต์สตรีมของ PDF ที่เก็บไบต์ของไฟล์ภายนอก พร้อม parameters dictionary ที่บันทึกขนาดเดิม วันที่ และ checksum (ISO 32000-2 §7.11.4)
- EmbeddedFiles name tree — แผนที่ที่เรียงลำดับใน document catalog ที่แสดงรายการไฟล์ฝังตัวตามชื่อ เพื่อให้โปรแกรมอ่านระบุไฟล์แนบได้โดยไม่ต้องสแกนทั้งเอกสาร
- Associated file — ไฟล์ฝังตัวที่ถูกผูกเข้ากับส่วนหนึ่งของเอกสารด้วยการเชื่อมโยง
/AF(บน document catalog หน้าหนึ่ง หรืออ็อบเจกต์) และบรรจุAFRelationshipที่ระบุว่ามันเกี่ยวข้องกับเนื้อหานั้นอย่างไร กรณีระดับเอกสาร — file specification ในอาร์เรย์/AFของ catalog — คือกรณีที่หน้านี้เน้น (ISO 32000-2 §14.13.3) - AFRelationship — คีย์ใน file specification ที่ค่าของมันระบุชื่อความสัมพันธ์ (ISO 32000-2 §7.11.3) มันรับหนึ่งในแปดค่ามาตรฐาน (
Source,Data,Alternative,Supplement,EncryptedPayload,FormData,Schema,Unspecified) หรือค่ากำหนดเอง;Dataคือค่าที่เพย์โหลด e-invoice แบบไฮบริดใช้ - PDF/A-3 — โปรไฟล์การเก็บถาวร ISO 19005-3 ที่อนุญาตให้ฝังไฟล์รูปแบบใดก็ได้ ทำให้เอกสารไฮบริดที่สอดคล้องกับมาตรฐานเป็นไปได้
- Hybrid invoice — ไฟล์ PDF เดียวที่เป็นทั้งหน้าที่มนุษย์อ่านได้และเพย์โหลดใบแจ้งหนี้ฝังตัวที่เครื่องอ่านได้