Meta veriler: XMP paketi oluşturma ve akış tabanlı okuma
Bir bakışta
“Bir bakışta” başlıklı bölümMetadata modülü, motorun Extensible Metadata Platform (XMP) katmanıdır. Portable Document Format (PDF) dosyasının meta veri akışı olarak taşıdığı XMP paketini oluşturur. Mevcut bir paketi, belgenin tamamını belleğe yüklemeden okur. Motora ait denetim izi XMP uzantısını üretir.
Kurulum
“Kurulum” başlıklı bölümcomposer require nextpdf/core:^3Kavramsal genel bakış
“Kavramsal genel bakış” başlıklı bölümBir PDF, ISO 32000-2 §14.3’te açıklandığı gibi, belge düzeyindeki meta verileri belge kataloğuna bağlı bir meta veri akışında XMP paketi olarak saklar. Bu modül, söz konusu paketin üretiminden ve tüketiminden sorumludur. API yüzeyi bilinçli olarak küçük ve odaklıdır: NextPDF\Metadata\Xmp altında üç sınıf.
XmpMetadataBuilder paketi üretir. Bir özellik kümesini, standart <?xpacket?> işleme yönergeleriyle sarmalanmış, iyi biçimlendirilmiş bir XMP belgesine seri hâle getirir. XMP belirtiminde sabitlenen kurallı paket globally unique identifier (GUID) değerini ve bayt sırası işaretini kullanır. Çıktı, Writer’ın meta veri akışı olarak gömdüğü bayt dizisidir; bu, §14.3’te açıklanan PDF içi XMP gösterimidir.
XmpStreamReader bir paketi tüketir. Kötücül girdiye karşı dayanıklı olacak şekilde tasarlanmıştır. Kaynak, ayrıştırmadan önce 64 KB’lık parçalar hâlinde sınırlı boyutlu bir geçici dosyaya akıtılır. Okuyucu, bu yazma işlemi sırasında toplam bayt üst sınırı uygular. libxml varlık yükleyicisi ayrıştırma sırasında null olarak ayarlanır ve sonrasında geri yüklenir. Bir DOCTYPE kesin ret tetikler. iterateProperties(), tüm ağacı bellekte oluşturmadan her yaprak öğe için (namespaceUri, localName, textContent) demetleri veren bir üreteç döndürür; herhangi bir anda ayrıştırıcıda yalnızca geçerli öğe ve onun metin düğümü etkindir. Aşırı büyük bir paket PacketTooLargeException oluşturur; bozuk biçimli Extensible Markup Language (XML), bir DOCTYPE veya UTF-8 dışı girdi ise InvalidConfigException oluşturur.
XmpAuditFieldEmitter motora özgü uzantıdır. Bir AuditReport kaydını, nextpdfAudit ad alanı altında özel bir XMP alanına işler; böylece bir belgenin uygunluk denetimi dosyayla birlikte yan dosya olarak değil, standartlara uygun XMP olarak taşınır. İşlenen AuditReport, üretici tarafından oluşturulmaz. Çağıran taraf, CssRenderingMode::Audit altında, çağıranın sağladığı bir auditCollector (Config(auditCollector: ...) aracılığıyla yapılandırılır) ile bir işleme çalıştırarak zenginleştirmeyi etkinleştirir. Toplayıcının akışını çağıran taraf yönetir: çağıran taraf onu besler ve üretici, topladığı her şeyi işler. Çekirdek XMP API yüzeyinden daha yenidir (@since 5.4.0). Oluşturucu ve okuyucu @since 2.0.0 sürümündendir.
API yüzeyi
“API yüzeyi” başlıklı bölüm| Sınıf | Temel üyeler | Rol |
|---|---|---|
XmpMetadataBuilder | build(): string, XPACKET_GUID, XPACKET_BOM | Bir özellik kümesini bir XMP paketine seri hâle getirir (@since 2.0.0) |
XmpStreamReader | iterateProperties(mixed $source, int $byteCap = DEFAULT_BYTE_CAP): \Generator, DEFAULT_BYTE_CAP | Sınırlı, akış tabanlı, DOCTYPE’ı reddeden XMP okuyucusu (@since 2.0.0) |
PacketTooLargeException | şu sınıftan türetilir: NextPdfException | Bir XMP paketi bayt üst sınırını aştığında oluşturulur (@since 2.0.0) |
XmpAuditFieldEmitter | render(?AuditReport $report): string, NAMESPACE_URI | Denetim izini özel bir XMP alanı olarak işler (@since 5.4.0) |
Tam PHPDoc tablosunu oluşturmak için composer docs:generate-api-php -- --module=Metadata komutunu çalıştırın.
Kod örneği — hızlı başlangıç
“Kod örneği — hızlı başlangıç” başlıklı bölümBelirlenmiş bir bayt üst sınırıyla, mevcut bir XMP paketinden özellikleri akış tabanlı olarak çıkarın.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Metadata\Xmp\XmpStreamReader;
$reader = new XmpStreamReader();
foreach ($reader->iterateProperties(file_get_contents('/srv/in/xmp.xml'), byteCap: 1_048_576) as [$ns, $name, $value]) { printf("%s:%s = %s\n", $ns, $name, $value);}Kod örneği — üretim
“Kod örneği — üretim” başlıklı bölümBir paketi savunmacı biçimde okuyun ve ham ayrıştırıcı hatalarının dışarı sızmasına izin vermek yerine modülün türlendirilmiş hatalarını uygulama düzeyindeki bir sonuca eşleyin.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Exception\InvalidConfigException;use NextPDF\Metadata\Xmp\PacketTooLargeException;use NextPDF\Metadata\Xmp\XmpStreamReader;use Psr\Log\LoggerInterface;
final readonly class XmpIngestService{ public function __construct( private XmpStreamReader $reader, private LoggerInterface $logger, ) {}
/** * @param resource|string $source A stream resource or XMP byte string. * * @return array<string, string> Flattened "ns:name" => value map. */ public function ingest(mixed $source): array { $properties = [];
try { // Cap untrusted XMP at 4 MB regardless of the 1 GiB default. foreach ($this->reader->iterateProperties($source, byteCap: 4_194_304) as [$ns, $name, $value]) { $properties["{$ns}:{$name}"] = $value; } } catch (PacketTooLargeException $e) { $this->logger->warning('XMP packet exceeded ingest cap; rejected.', ['error' => $e->getMessage()]);
return []; } catch (InvalidConfigException $e) { $this->logger->warning('XMP packet malformed or unsafe; rejected.', ['error' => $e->getMessage()]);
return []; }
return $properties; }}Sınır durumları ve dikkat edilecek noktalar
“Sınır durumları ve dikkat edilecek noktalar” başlıklı bölümXmpStreamReaderherhangi bir DOCTYPE’ı doğrudan reddeder. Bu, bir doğrulama ayrıntısı değil, bir XML External Entity (XXE) savunmasıdır; DOCTYPE’a ihtiyaç duyan bir paket kabul edilmez. Bunu yukarı akışta temizleyin.- Bayt üst sınırı varsayılan olarak 1 GiB değerindedir (
DEFAULT_BYTE_CAP). Bu varsayılan bir öneri değil, tavandır. Güvenilmeyen girdi için dar birbyteCapdeğeri geçirin. iterateProperties()bir üreteçtir. Bir kez tüketin; ikinci kez yinelemek önceki çıktıyı yeniden oynatmaz.- Okuyucu, libxml varlık yükleyicisini ayrıştırma sırasında null olarak ayarlar ve sonra geri yükler. Aynı istek içinde varlık yükleyicisine bağımlı başka bir libxml tabanlı ayrıştırma varsa, bunu o ayrıştırmayla eşzamanlı çalıştırmayın.
XmpAuditFieldEmitter::render(null)geçerlidir ve boş çıktı verir; null birAuditReport, hata değil, “denetim yok” anlamına gelir.
Performans
“Performans” başlıklı bölümOluşturucu, özellik sayısına göre doğrusal çalışır. Okuyucunun bellek kullanımı belge boyutuna göre değil, en uzun tekil metin dizisine göre belirlenir; çünkü ayrıştırıcıda yalnızca geçerli öğe etkindir ve büyük paketler belleğe yüklenmek yerine akıtılır. Varsayılan referans iş yükü, 1500 ms duvar saati / 64 MB tepe kullanım bütçesi içinde kalır. Yeniden üretilebilirlik profili structural değerindedir: bir XMP paketi değişiklik zaman damgalarını kaydeder. Aynı mantıksal meta veriden yapılan iki oluşturma, yapıları aynı olsa da bu alanlarda farklılık gösterir.
Güvenlik notları
“Güvenlik notları” başlıklı bölümXmpStreamReader güvenilmeyen XML’i ayrıştırır ve bu doğrultuda güçlendirilmiştir. Uygulanan bayt üst sınırı ve akış tabanlı parçalama, bellek tüketimini yükselterek yapılan bir hizmet reddi saldırısını sınırlar. DOCTYPE’ın reddedilmesi XXE’yi kapatır. LIBXML_NONET, ağ üzerinden varlık çözümlemesini engeller. UTF-8 dışı girdi reddedilir. Yine de, dışarıdan gelen herhangi bir paket için gigabaytlık varsayılana güvenmek yerine dağıtımınıza uygun bir byteCap değeri belirleyin. XMP özellik değerleri uygulamaya yeniden girdiğinde, bunları güvenilmeyen dizeler olarak değerlendirin. Motor tehdit modeli için /modules/core/security/ bölümüne bakın.
Uygunluk
“Uygunluk” başlıklı bölümÜretilen paket, yani XmpMetadataBuilder çıktısı, ISO 32000-2 §14.3’te tanımlanan PDF içi XMP meta veri akışı gösterimidir (). XMP’nin seri hâle getirme biçimi ise doğrulanabilir alıntı külliyatında yer almayan XMP belirtimi (ISO 16684-1) tarafından yönetilir. Bu gereksinime parça sabitlemesiyle değil, numarasıyla başvurulur. Bunlar, src/Metadata/Xmp/ tarafından üretilen ve tests/Unit/Metadata/Xmp/ tarafından sınanan uygulama gerçekleridir. Bir profil (PDF/A, PDF/UA) için uçtan uca meta veri uygunluğu, /modules/core/conformance/ bölümünde açıklanan oracle ve golden setleri tarafından doğrulanır.
Ayrıca bakınız
“Ayrıca bakınız” başlıklı bölüm- Document modülü — Document Part Metadata (DPM) ile eşleştirilen DPart ağacı.
- Audit modülü — üreticinin işlediği
AuditReportkaydını üretir. - Writer modülü — paketi meta veri akışı olarak gömer.
- Uygunluk genel bakışı
- Motor güvenlik modeli