Bir PDF, bir kaptır: gömülü dosyalar ve ilişkili veriler
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
Bir bakışta
“Bir bakışta” başlıklı bölümÇoğu insan bir PDF’yi bir sayfa yığını olarak hayal eder. Gördüğünüz kısım odur. Ama bir PDF aynı zamanda bir kaptır ve içinde bütün başka dosyalar taşıyabilir — bir elektronik tablo, bir XML yükü, özgün kaynak belge — hepsi, başkasına verdiğiniz aynı tek dosyada paketlenmiş hâlde.
Bu sayfa bunun nasıl çalıştığını açıklar: byte’ları saklayan gömülü-dosya akışını, onları listeleyen ad ağacını ve bir ekin orada öylece durup durmadığına yoksa gerçekten bir şey ifade edip etmediğine karar veren tek anahtarı.
Bunun önemi nedir
“Bunun önemi nedir” başlıklı bölümTipsiz bir ek ile tipli bir ek, bir insana özdeş görünür. İkisi de bir PDF’nin içinde yolculuk eden bir dosyadır ve — bu motorda — ikisi de belgeyle ilişkilendirilmiştir. Aradaki fark, birinin bir makineye ne işe yaradığını söylemesi, diğerininse ilişkiyi makinenin tahmin etmesi için boş bırakmasıdır.
Bu fark, bir hibrit e-fatura için işin tamamıdır. Bir vergi platformu sizin fatura sayfanızı okumaz; gömdüğünüz XML’i okur. O XML, görünür belge için fatura verisi olarak değil de ayrımsız bir yığın olarak eklenmişse, uyumlu bir okuyucunun onun işlenecek yük olduğunu güvenilir biçimde bilmesinin bir yolu yoktur. Sayfa kusursuz görünür. Fatura reddedilir. Başarısızlık, ardında bekletilmiş bir ödemeyle birlikte, günler sonra gelir.
İlişkiyi, dosyayı üreten katmanda doğru kurmak, onu bir defada bir reddedilmiş fatura üzerinden keşfetmekten çok daha ucuzdur.
Kısa açıklama
“Kısa açıklama” başlıklı bölüm- Bir PDF, herhangi bir dosyanın byte’larını bir gömülü dosya akışı olarak gömebilir (Spec: ISO 32000-2, §7.11.4ISO 32000-2 §7.11.4). Akış, veriye ek olarak küçük bir parametreler sözlüğü taşır: özgün boyut, tarihler ve bir sağlama toplamı.
- Gömülü dosyalar
EmbeddedFilesad ağacında kataloglanır; böylece bir okuyucu, tüm belgeyi taramadan onları ada göre listeleyebilir. - Bir ilişkili dosya bir adım daha ileri gider: bir
AFRelationshipbeyan eder (Spec: ISO 32000-2, §7.11.3ISO 32000-2 §7.11.3) — sekiz standart değerden biri (Source,Data,Alternative,Supplement,EncryptedPayload,FormData,Schema,Unspecified) ya da özel bir değer — dosyanın, eklendiği içerikle nasıl ilişkili olduğunu söyleyerek. - Bu tipli ilişki, hibrit e-faturaların (ZUGFeRD / Factur-X) ve PDF/A-3 eklerinin arkasındaki mekanizmadır (Spec: ISO 19005-3, PDF/A-3ISO 19005-3 PDF/A-3).
- NextPDF, ham kap ilkellerini çekirdekte destekler: açık bir ilişkiyle birlikte
embedFile()veembedFileFromString(). Gelişmiş sürümler, bu ilkellerin üzerine özel EN 16931 / ZUGFeRD / Factur-X e-fatura gömücüsünü ekler.
NextPDF’nin yaklaşımı
“NextPDF’nin yaklaşımı” başlıklı bölümBunu, üst üste yığılmış iki katman olarak düşünün.
Alt katman depolamadır. Bir gömülü dosya akışı
(Spec: ISO 32000-2, §7.11.4ISO 32000-2 §7.11.4), özgün dosyanın byte’larının bir
PDF akış nesnesine sarılmış hâlidir; özgün boyutu, değişiklik tarihini ve
sıkıştırılmamış verinin bir sağlama toplamını kaydeden bir parametreler sözlüğüyle
birlikte. Akışa, /EF sözlüğü gömülü dosya akışına işaret eden bir dosya
belirtimi (file specification) sözlüğü üzerinden ulaşılır — akışın kendisi /EF
taşımaz. Bir okuyucu, dosyayı byte byte geri çekebilir. Bu dosyaları bulunabilir
kılmak için belge kataloğu bir EmbeddedFiles ad ağacı tutar — bir addan her dosya
belirtimine giden sıralı bir eşleme — böylece bir görüntüleyici her sayfayı dolaşmadan
“bu PDF’nin içinde 3 dosya var” diye listeleyebilir.
Üst katman anlamdır. Tek başına, gömülü bir dosya yalnızca mevcuttur.
İlişkili-dosyalar mekanizması (Spec: ISO 32000-2, §14.13ISO 32000-2 §14.13) bir
dosyayı bir şeye — tüm belgeye, bir sayfaya, bir grafik nesnesine — bağlar ve onu bir
AFRelationship ile damgalar. ISO 32000-2, sekiz standart değerden oluşan küçük bir
sözcük dağarı tanımlar (Spec: ISO 32000-2, §7.11.3ISO 32000-2 §7.11.3) ve özel
değerlere de izin verir; her standart değer kesin bir soruya yanıt verir:
AFRelationship | Dosya hakkında ne iddia ettiği |
|---|---|
Source | Bu, görünür içeriğin üretildiği kaynak malzemedir (örneğin, özgün kelime işlemci belgesi). |
Data | Bu, görünür içeriğe bağlı yapılandırılmış veridir — kanonik durum, oluşturulmuş bir fatura sayfasının arkasındaki fatura XML’idir. |
Alternative | Bu, aynı içeriğin alternatif bir gösterimidir (örneğin, bir ses ya da video sürümü). |
Supplement | Bu, içeriği genişleten ama onun bir parçası olmayan tamamlayıcı malzemedir. |
EncryptedPayload | Gömülü dosya, PDF’nin opak bir yığın olarak sardığı şifrelenmiş bir yüktür. |
FormData | Dosya, form verisidir (FDF, XFDF ya da bir XML form yükü). |
Schema | Dosya, bir Data dosyasının yapısını tanımlayan bir şemadır (örneğin, XML verisi için bir XSD ya da bir JSON Schema). |
Unspecified | İlişki kasıtlı olarak belirtilmemiştir. Dürüsttür, ama bir makineye hiçbir şey söylemez. |
Bu sekizin ötesinde, standart uygulamaya özgü özel ilişki değerlerine de izin verir; böylece sözcük dağarı sabit değil, genişletilebilirdir.
Bir ilişkili dosya, tek bir anahtarla değil, birlikte çalışan iki şeyle tanımlanır.
/AF ilişkilendirmesi, dosya belirtimini belgenin bir parçasına bağlar; dosya
belirtimindeki AFRelationship anahtarı ise anlamsal ilişkiyi belirtir.
İlişkilendirme noktasındaki (belge kataloğu, bir sayfa ya da bir nesne) /AF girdisi
bir dizidir — bu dizi, genellikle dolaylı referanslar olarak, bir veya daha fazla
dosya belirtimi sözlüğü içerir; /AF tek bir referans değildir. Belge düzeyinde bir
ilişkili dosya, belge kataloğunun /AF dizisinde listelenen ve kendi
AFRelationship değerini taşıyan dosya belirtimidir. O elektronik tabloyu
Unspecified olarak işaretlerseniz, onu belgeyle ilişkilendirmiş ama bir makineye
neden olduğu hakkında hiçbir şey söylememiş olursunuz. Aynı elektronik tabloyu
Data olarak işaretlerseniz, her uyumlu okuyucuya onun ne olduğunu ve ne işe
yaradığını söylemiş olursunuz. Byte’lar aynıdır. Anlambilim değildir.
İşte bu yüzden e-fatura durumu “bir XML dosyası ekle” değildir. “Bu XML’i, bu belge
için Data ilişkili dosyası olarak, uyumlu bir PDF/A-3 taşıyıcısının içine göm”dür —
fatura geçerliliği ve hukuki kabul ise taşıyıcının gerçekleştirmediği ayrı
denetimler olarak kalır. Akış dört aşamadan oluşur ve onu doğru tutan şey, sıradır.
- 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).
O dördüncü aşama, PDF/A-3’ün neden ayrı bir profil olarak var olduğudur. Daha eski
arşivleme profilleri neyin gömülebileceğini kısıtlıyordu; PDF/A-3
(Spec: ISO 19005-3, PDF/A-3ISO 19005-3 PDF/A-3), herhangi bir biçimdeki
dosyaların uyumlu bir arşivleme belgesinin içinde yolculuk etmesine izin veren
kısımdır. Gömülü yüke izin verir — o yükü doğrulamaz ya da ona hukuki statü
kazandırmaz. Onsuz, hibrit fatura — bir kişinin okuduğu sayfa ve bir vergi sisteminin
ayrıştırdığı verinin ikisi birden olan tek dosya — hiç de uyumlu bir arşivleme PDF/A
belgesi olamazdı; faturanın geçerli ve hukuken kabul edilip edilmediği ise ayrı
bir soru olarak kalır. Gelişmiş sürümlerin eklediği özel e-fatura gömücüsü, tam
da bunun üzerindeki kolaylık dikişidir: yükü gömer, ilişkiyi Data olarak ayarlar ve
onu doğru biçimde kaydeder; böylece kap tesisatını elle kurmazsınız. Daha derin
faturalama ve arşivleme mekanikleri, aşağıda bağlantısı verilen iki komşu sayfada
yaşar; bu sayfa, ikisinin de üzerinde durduğu kabı konu alır.
Pratik örnek
“Pratik örnek” başlıklı bölümKüçük, eksiksiz bir program. Önemli olan iki çağrı, tipsiz bir ilişkili dosya ile
tipli bir ilişkili dosya arasındaki farktır — ve ilişki, ayarlamanız gereken açık
bir bağımsız değişkendir. Bu motorda, her iki çağrı da bir ilişkili dosya üretir:
embedFile() ve embedFileFromString(), dosya belirtimini her zaman belge
kataloğunun /AF dizisine kaydeder; dolayısıyla ilişkinin değiştirdiği tek şey,
ilişkilendirmenin ne anlama geldiğidir. Varsayılanı Unspecified’dır; bu da dosyayı
ilişkilendirir ama bir makineye nedeni hakkında hiçbir şey söylemez; bir e-fatura yükü
için onu Data olarak ayarlarsınız ki bir okuyucu onu bulabilsin.
<?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' ilişkisi yanılmaya yer bırakmaz. İlk ek — Unspecified bırakılmış olan —
yine de, yalnızca belirtilmiş bir anlam olmadan, ilişkilendirilmiştir. Her iki çağrı
için de motor, gömülü dosya akışını yazar, dosyayı EmbeddedFiles ad ağacına ekler,
dosya belirtimini belge kataloğunun /AF dizisinde listeler ve belirttiğiniz
ilişkiyi kaydeder — sizin yerinize bir tane seçmez. Bu motorda yalnızca-ad-ağacı kipi
yoktur: bu yolla gömdüğünüz her dosya belgeyle ilişkilendirilmiş bir dosyadır; bu
nedenle kontrol ettiğiniz tek kol ilişkidir.
Yaygın yanlış kanı
“Yaygın yanlış kanı” başlıklı bölümSık görülen varsayım, “gömülü” ve “ilişkili”nin aynı şeyin iki sözcüğü olduğudur.
Değiller. Gömülü, depolamayla ilgilidir — byte’lar PDF’nin içindedir. İlişkili,
bağlamayla ilgilidir — dosya belirtimi, belgenin bir parçasındaki bir /AF dizisinde
listelenir ve bir AFRelationship taşır. Soyut PDF modelinde bir dosya, hiç
ilişkilendirilmeden ad ağacına gömülebilir; NextPDF’nin embedFile() yolu onu öyle
bırakmaz — /AF ilişkilendirmesini her zaman yazar — dolayısıyla bu motor için açık
soru asla bir dosyanın ilişkilendirilip ilişkilendirilmediği değil, ilişkinin ne
söylediğidir.
İkinci bir tuzak: bir görüntüleyicinin hangi ekin fatura olduğunu “çözeceğini”
varsaymak. Uyumlu bir okuyucunun tahmin etmesi beklenmez. İlişkisi Data diyen
dosyayı arar. İlişkiyi Unspecified bırakırsanız, yükü ilişkilendirmiş ama makineye
onun rolü hakkında yararlı hiçbir şey söylememiş olursunuz.
Sınırlar ve hudutlar
“Sınırlar ve hudutlar” başlıklı bölümKap mekanizması, dürüst olmaya değer bir biçimde güçlüdür: embedFile(), PHP
sürecinin okuyabildiği herhangi bir yolu okur. Özellik budur — ve hudut da budur.
Motor, kendisine verilen byte’ları ekler; bir yolun amaçladığınız bir yol olup
olmadığına sizin yerinize karar vermez ve karar veremez.
| Edition | Availability |
|---|---|
| Core |
|
| Pro | Not in this edition |
| Enterprise | Not in this edition |
Açıkça belirtmeye değer iki sınır daha:
- Gömmek, doğrulamak değildir. Motor, kendisine verdiğiniz byte’ları taşır. Gömülü XML’in uyumlu bir fatura yükü olup olmadığı, bir doğrulayıcı tarafından yanıtlanan ayrı bir sorudur — faturalama sayfasına bakın.
- Tipli bir ek, tek başına uyumlu bir arşivleme dosyası değildir. Hibrit dosyayı hukuki bir PDF/A-3 belgesi yapmak, arşivleme kipini ve bağımsız bir uygunluk denetimini gerektirir — arşivleme sayfasına bakın.
İlgili belgeler
“İlgili belgeler” başlıklı bölüm- Faturalar ve e-faturalama — bu
mekanizmanın olanaklı kıldığı kullanım durumu: makine okuyabilir bir faturayı
Datailişkili dosyası olarak taşıyan hibrit bir PDF. - Arşivleme ve PDF/A — taşıyıcının neden bir PDF/A-3 dosyası olduğu ve uygunluğun neyi vaat edip neyi etmediği.
- Bir PDF dosyasının anatomisi — ad ağacının ve belge kataloğunun dosya yapısında nerede durduğu.
- Akışlar ve filtreler — gömülü bir dosyanın byte’larının bir akış nesnesinin içinde nasıl saklanıp sıkıştırıldığı.
Sözlük
“Sözlük” başlıklı bölüm- Gömülü dosya akışı (embedded file stream) — özgün boyutunu, tarihlerini ve bir sağlama toplamını kaydeden bir parametreler sözlüğüyle birlikte, harici bir dosyanın byte’larını tutan bir PDF akış nesnesi (ISO 32000-2 §7.11.4).
- EmbeddedFiles ad ağacı — belge kataloğundaki, gömülü dosyaları ada göre listeleyen sıralı eşleme; böylece bir okuyucu tüm belgeyi taramadan ekleri listeleyebilir.
- İlişkili dosya (associated file) — bir
/AFilişkilendirmesiyle (belge kataloğu, bir sayfa ya da bir nesne üzerinde) belgenin bir parçasına bağlanan ve o içerikle nasıl ilişkili olduğunu belirten birAFRelationshiptaşıyan gömülü bir dosya; bu sayfanın merkeze aldığı, belge düzeyindeki durumdur — kataloğun/AFdizisindeki dosya belirtimi (ISO 32000-2 §14.13.3). - AFRelationship — değeri ilişkiyi adlandıran dosya-belirtimi anahtarı (ISO
32000-2 §7.11.3). Sekiz standart değerden birini (
Source,Data,Alternative,Supplement,EncryptedPayload,FormData,Schema,Unspecified) ya da özel bir değer alır;Data, bir hibrit e-fatura yükünün kullandığı değerdir. - PDF/A-3 — herhangi bir biçimdeki dosyaların gömülmesine izin vererek uyumlu bir hibrit belgeyi olanaklı kılan ISO 19005-3 arşivleme profili.
- Hibrit fatura — hem insan okuyabilir bir sayfa hem de makine okuyabilir gömülü bir fatura yükü olan tek bir PDF dosyası.