Lewati ke konten

Contracts: 41 antarmuka publik (SPI)

NextPDF\Contracts adalah antarmuka penyedia layanan (SPI) publik: 41 antarmuka dan enum di bawah src/Contracts/ dengan tanda @stability eksplisit serta jaminan kompatibilitas mundur. Paket ekstensi, jembatan framework, serta edisi Pro dan Enterprise bergantung pada tipe-tipe ini, bukan pada kelas konkret.

Terminal window
composer require nextpdf/core:^3

Mesin ini mengekspos dua permukaan. Kelas konkret di bawah src/Core/, src/Html/, dan src/Writer/ tidak memiliki jaminan kompatibilitas dan dapat berubah di antara versi minor. Namespace Contracts bekerja secara berbeda. Namespace ini adalah kumpulan tipe terkurasi dengan tanda tangan yang dibekukan sesuai tingkat stabilitas yang dideklarasikan. Semua komponen di luar mesin bergantung pada namespace ini tanpa menjangkau lebih dalam. Cakupannya meliputi jembatan Laravel, Symfony, dan CodeIgniter, shim compat-tcpdf, NextPDF Server, serta edisi Pro dan Enterprise.

Setiap kontrak mendeklarasikan salah satu dari empat tingkat dalam PHPDoc-nya. Kontrak stable tidak mengizinkan perubahan yang merusak kompatibilitas pada rilis minor atau patch. Metode baru hanya diperkenalkan bersama implementasi standar. Kontrak experimental dapat berubah pada rilis minor dengan pemberitahuan penghentian (deprecation). Kontrak deprecated menyebutkan penggantinya. Sebagian kecil bersifat kontrak-saja, seperti StreamingWriterInterface dan CursorInterface. Tipe tersebut sudah diterbitkan dan dibekukan, tetapi belum ada implementasi produksi yang disertakan.

Daftar tingkat otoritatif adalah docs/extension-points.json (versi manifes 3.0.0, 67 titik yang diterbitkan di seluruh Contracts dan Event). Pengujian yang dapat diverifikasi mesin, tests/Unit/Contracts/StabilityContractTest.php, membaca manifes tersebut dan menggagalkan build pada lima kondisi. Pertama, tipe yang terdaftar tidak ada. Kedua, jenis hasil refleksi tidak sesuai dengan manifes. Ketiga, tanda PHPDoc @stability menyimpang dari manifes. Keempat, sebuah kontrak di bawah src/Contracts/ tidak ada dalam manifes. Kelima, tipe @internal masuk ke dalamnya. Permukaan kontrak tidak dapat menyimpang tanpa terdeteksi.

Kontrak terbagi ke dalam sembilan domain, masing-masing dibahas pada halaman tersendiri: konstruksi dokumen, penandatanganan, pengkodean barcode, tipografi, kebijakan keamanan, ekstraksi, observabilitas, dan streaming. Pembagian ini mencerminkan cara Anda mengadopsi mesin ini. Anda bergantung pada kontrak dokumen untuk menghasilkan berkas Portable Document Format (PDF). Anda bergantung pada kontrak penandatanganan untuk menambahkan tanda tangan. Anda bergantung pada kontrak kebijakan keamanan untuk membatasi HTML yang tidak tepercaya.

Resolusi implementasi opsional mengikuti satu pola di seluruh mesin. Core memeriksa keberadaan kelas konkret dengan class_exists() dan mengikatnya ke kontrak. LtvManagerInterface dan PdfAManagerInterface meresolusi implementasi Pro-nya dengan cara ini. Core tetap Apache-2.0 tanpa ketergantungan keras pada kode komersial.

KontrakJenisStabilitasSejakDomain
PdfDocumentInterfaceinterfacestable1.0.0document
DocumentFactoryInterfaceinterfacestable1.7.0document
ResettableServiceinterfacestable1.7.0document
OutputDestinationenumstable1.0.0document
Orientationenumstable1.0.0document
Alignmentenumstable1.0.0document
SignerInterfaceinterfacestable1.0.0signing
HsmSignerInterfaceinterfacestable1.0.0signing
DeferredSignerInterfaceinterfaceexperimental3.0.0signing
TimestampProviderInterfaceinterfaceexperimental3.0.0signing
LtvManagerInterfaceinterfacestable1.10.0signing
CryptoPolicyInterfaceinterfacestable1.9.0signing
Barcode1DEncoderInterfaceinterfacestable1.0.0barcode
Barcode2DEncoderInterfaceinterfacestable1.0.0barcode
BarcodeEncoderInterfaceinterfacestable3.0.0barcode
Gs1DataParserInterfaceinterfacestable1.0.0barcode
FontRegistryInterfaceinterfacestable1.7.0typography
TextPreprocessorInterfaceinterfacestable1.9.0typography
HtmlSecurityPolicyInterfaceinterfacestable3.1.0security-policy
ExternalResourcePolicyInterfaceinterfacestable4.0.0security-policy
InspectorInterfaceinterfaceexperimental2.2.0extraction
EmbeddingServiceInterfaceinterfaceexperimental2.1.0extraction
VectorIndexInterfaceinterfaceexperimental2.1.0extraction
JobNotificationInterfaceinterfaceexperimental2.2.0observability
SpectrumInterfaceinterfaceexperimental2.1.0observability
StreamingWriterInterfaceinterfaceexperimental3.1.0streaming
CursorInterfaceinterfaceexperimental3.1.0streaming

Tabel ini mencantumkan kontrak-kontrak utama. Tipe-tipe lainnya, termasuk objek transfer data (DTO) berbentuk value-object (TextSegment, TextPreprocessResult), sub-namespace EInvoice, enum perilaku (DegradationPolicy, UnderlineStyle), dan kontrak impor (ImportedFormObjectInterface, EmbeddedPdfObjectInterface, ChromeRenderResultInterface), didokumentasikan pada halaman domain di bawah Lihat juga. Daftar lengkap yang dapat dibaca mesin adalah docs/extension-points.json, yang dicerminkan ke .ai/contracts-map.md.

examples/01-hello-world.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Hello World');
$doc->addPage();
$doc->setFont('helvetica', '', 24);
$doc->cell(0, 15, 'Hello, NextPDF!', newLine: true);
$doc->save(__DIR__ . '/output/01-hello-world.pdf');

Document::createStandalone() mengembalikan Document konkret yang memenuhi PdfDocumentInterface. Gunakan petunjuk tipe (type-hint) antarmuka di dalam layanan Anda agar internal mesin tetap dapat ditukar.

examples/14-worker-factory.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\DocumentFactory;
use NextPDF\Core\PdfFactory;
use NextPDF\Graphics\ImageRegistry;
use NextPDF\Typography\FontRegistry;
// Created once at process boot in a RoadRunner/Swoole/Octane worker.
$fontRegistry = new FontRegistry();
$imageRegistry = new ImageRegistry(maxCacheBytes: 50 * 1024 * 1024);
$documentFactory = new DocumentFactory($fontRegistry, $imageRegistry);
$factory = PdfFactory::new()
->withCompress(true)
->withDocumentFactory($documentFactory);
for ($request = 1; $request <= 3; $request++) {
$doc = $factory->create();
$doc->setTitle("Worker Request #{$request}");
$doc->addPage();
$doc->setFont('helvetica', 'B', 16);
$doc->cell(0, 12, "Worker Request #{$request}", newLine: true);
$doc->save(__DIR__ . "/output/14-worker-request-{$request}.pdf");
}

DocumentFactory mengimplementasikan DocumentFactoryInterface. Factory ini menyimpan singleton FontRegistryInterface dan ImageRegistryInterface yang hidup sepanjang proses dan menyuntikkannya ke setiap Document sekali pakai, sehingga worker mengurai setiap fon sekali saja untuk ribuan permintaan.

  • Tipe kontrak-saja dapat dikompilasi tetapi tidak memiliki dukungan saat runtime. Ekspresi new terhadap StreamingWriterInterface atau CursorInterface akan gagal karena belum ada kelas yang mengimplementasikannya. Perlakukan keduanya sebagai application programming interface (API) yang dideklarasikan di muka.
  • Tanda PHPDoc @stability adalah sumber kebenaran untuk satu tipe. docs/extension-points.json adalah sumber kebenaran untuk himpunannya. Ketika keduanya bertentangan, StabilityContractTest gagal. Jangan sembunyikan pertentangan itu dengan menyunting salah satu sisi.
  • experimental tidak berarti tidak stabil dalam praktik. Itu berarti jaminan kompatibilitasnya lebih lemah. Baca bidang bc_promise setiap kontrak di .ai/contracts-map.md sebelum mengikatnya.
  • Kelas @internal tidak pernah menjadi kontrak meskipun paket lain secara teknis dapat mereferensikannya. Pengujian stabilitas menolak setiap tipe @internal yang muncul dalam manifes.
  • Menambahkan metode ke antarmuka stable merupakan perubahan yang merusak kompatibilitas bagi para pengimplementasi kecuali metode itu disertai implementasi standar. Mesin menambahkan kemampuan melalui antarmuka baru, bukan dengan memperluas antarmuka yang sudah ada.

Memprogram terhadap Contracts tidak menambah biaya runtime yang terukur: petunjuk tipe antarmuka diresolusi pada waktu penautan, bukan setiap pemanggilan. performance_budget untuk contoh worker pada halaman ini adalah 1500 ms wall dan puncak 64 MB untuk tiga dokumen. Penguraian fon pada permintaan pertama mendominasi anggaran tersebut. Permintaan berikutnya menggunakan kembali cache registri dan turun menjadi kerja terkait kontrak dalam orde milidetik satu digit. Model biayanya adalah O(1) per pengiriman kontrak; pekerjaannya berada di implementasi konkret, yang didokumentasikan pada setiap halaman domain.

SPI juga merupakan batas keamanan. HtmlSecurityPolicyInterface dan ExternalResourcePolicyInterface adalah kontrak yang menolak secara baku (deny-by-default) dan membatasi apa yang dapat dilakukan HTML tidak tepercaya sebelum mencapai renderer. CryptoPolicyInterface mengatur pemilihan algoritme dan kekuatan kunci untuk penandatanganan dan enkripsi. Karena ini adalah kontrak, Anda dapat menyediakan kebijakan yang lebih ketat tanpa melakukan fork pada mesin. Ikat ke tingkat stable untuk kebijakan apa pun yang relevan dengan keamanan. Kontrak kebijakan eksperimental dapat berubah bentuk antarrilis minor. Halaman domain penandatanganan dan kebijakan keamanan memuat model ancaman lengkap serta referensi normatif.

Tinjauan ini tidak membuat klaim normatif langsung; setiap halaman domain merender blok citations-nya sendiri. Kontrak penandatanganan dipetakan ke ISO 32000-2 §12.8 (tanda tangan digital) dan ETSI EN 319 142 (baseline PAdES). Manajer PDF/A dipetakan ke ISO 19005-4. Lihat halaman penandatanganan, kebijakan keamanan, dan ekstraksi untuk tabel kesesuaian tingkat klausa.

Edisi Pro dan Enterprise menyediakan kode produksi di balik beberapa kontrak inti: LtvManagerInterface (validasi jangka panjang), PdfAManagerInterface (penegakan PDF/A), Hardware Security Module (HSM) dan penanda tangan yang ditangguhkan, encoder barcode, serta kontrak embedding dan vector-index. Core menerbitkan dan membekukan antarmuka; paket Premium mengirimkan implementasinya. Ini menjaga mesin sumber terbuka tetap Apache-2.0 dan memberi penerapan komersial peningkatan siap pakai tanpa perubahan API.