コントラクト:41 個の公開インターフェイス(SPI)
NextPDF\Contracts は公開サービスプロバイダーインターフェイス(SPI)です。src/Contracts/ 配下の 41 個のインターフェイスと列挙型で構成され、いずれも明示的な @stability タグと後方互換性の保証を備えています。拡張パッケージ、フレームワークブリッジ、Pro エディションおよび Enterprise エディションは、具象クラスではなく、これらの型を対象にプログラミングします。
インストール
「インストール」という見出しのセクションcomposer require nextpdf/core:^3概念の概要
「概念の概要」という見出しのセクションエンジンは 2 つの側面を分離しています。src/Core/、src/Html/、src/Writer/ 配下の具象クラスには互換性の保証がありません。これらはマイナーバージョン間で自由に変更されます。Contracts 名前空間はその逆です。ここは厳選された型の集合であり、各型が宣言する安定性ティアに従ってシグネチャが凍結されています。エンジン外部のものはすべて、この名前空間に依存し、それより深い部分には依存しません。これには Laravel、Symfony、CodeIgniter の各ブリッジ、compat-tcpdf シム、NextPDF Server、Pro エディションおよび Enterprise エディションが含まれます。
各コントラクトは、その PHPDoc で 4 つのティアのいずれか 1 つを宣言します。stable コントラクトは、マイナーリリースまたはパッチリリースでの破壊的変更を一切許容しません。新しいメソッドは、デフォルト実装を伴う場合にのみ追加されます。experimental コントラクトは、非推奨通知を伴ってマイナーリリースで変更される場合があります。deprecated コントラクトは、置き換え先を明示します。StreamingWriterInterface や CursorInterface のように、コントラクトだけが存在するものも少数あります。これらの型は公開され凍結されていますが、本番向けの実装はまだ提供されていません。
正式なティアの一覧は docs/extension-points.json です(マニフェストバージョン 3.0.0、Contracts と Event にまたがる 67 個の公開ポイントを含みます)。機械的に検証できるテスト tests/Unit/Contracts/StabilityContractTest.php が、そのマニフェストを読み取ります。このテストは、次の 5 つの条件でビルドを失敗させます。1 つ目は、一覧に記載された型が存在しない場合です。2 つ目は、リフレクションで得られた種別がマニフェストと食い違う場合です。3 つ目は、@stability PHPDoc タグがマニフェストから乖離している場合です。4 つ目は、src/Contracts/ 配下のコントラクトがマニフェストに存在しない場合です。5 つ目は、@internal 型がそこに混入している場合です。コントラクトの公開面は、検知されないまま乖離することはありません。
コントラクトは 9 つのドメインに分類され、それぞれに専用ページがあります。ドキュメント構築、署名、バーコードエンコード、タイポグラフィ、セキュリティポリシー、抽出、可観測性、ストリーミングです。この分割は、インテグレーターがエンジンを導入する流れを反映しています。PDF を生成するには、ドキュメントコントラクトに依存します。署名を追加するには、署名コントラクトに依存します。信頼できない HTML を制約するには、セキュリティポリシーコントラクトに依存します。
オプション実装の resolve(解決)は、エンジン全体で 1 つのパターンに従います。Core は class_exists() で具象クラスの存在を確認し、それをコントラクトにキャストします。LtvManagerInterface と PdfAManagerInterface は、この方法で Pro 実装を解決します。したがって Core は Apache-2.0 のまま保たれ、商用コードへのハードな依存を持ちません。
API の表面
「API の表面」という見出しのセクション| コントラクト | 種別 | 安定性 | 導入バージョン | ドメイン |
|---|---|---|---|---|
PdfDocumentInterface | interface | stable | 1.0.0 | document |
DocumentFactoryInterface | interface | stable | 1.7.0 | document |
ResettableService | interface | stable | 1.7.0 | document |
OutputDestination | enum | stable | 1.0.0 | document |
Orientation | enum | stable | 1.0.0 | document |
Alignment | enum | stable | 1.0.0 | document |
SignerInterface | interface | stable | 1.0.0 | signing |
HsmSignerInterface | interface | stable | 1.0.0 | signing |
DeferredSignerInterface | interface | experimental | 3.0.0 | signing |
TimestampProviderInterface | interface | experimental | 3.0.0 | signing |
LtvManagerInterface | interface | stable | 1.10.0 | signing |
CryptoPolicyInterface | interface | stable | 1.9.0 | signing |
Barcode1DEncoderInterface | interface | stable | 1.0.0 | barcode |
Barcode2DEncoderInterface | interface | stable | 1.0.0 | barcode |
BarcodeEncoderInterface | interface | stable | 3.0.0 | barcode |
Gs1DataParserInterface | interface | stable | 1.0.0 | barcode |
FontRegistryInterface | interface | stable | 1.7.0 | typography |
TextPreprocessorInterface | interface | stable | 1.9.0 | typography |
HtmlSecurityPolicyInterface | interface | stable | 3.1.0 | security-policy |
ExternalResourcePolicyInterface | interface | stable | 4.0.0 | security-policy |
InspectorInterface | interface | experimental | 2.2.0 | extraction |
EmbeddingServiceInterface | interface | experimental | 2.1.0 | extraction |
VectorIndexInterface | interface | experimental | 2.1.0 | extraction |
JobNotificationInterface | interface | experimental | 2.2.0 | observability |
SpectrumInterface | interface | experimental | 2.1.0 | observability |
StreamingWriterInterface | interface | experimental | 3.1.0 | streaming |
CursorInterface | interface | experimental | 3.1.0 | streaming |
この表は主要なコントラクトを示しています。残りの型 — 値オブジェクト DTO(TextSegment、TextPreprocessResult)、EInvoice サブ名前空間、振る舞いを表す列挙型(DegradationPolicy、UnderlineStyle)、インポートコントラクト(ImportedFormObjectInterface、EmbeddedPdfObjectInterface、ChromeRenderResultInterface) — は、関連項目 配下のドメインページで説明しています。機械可読な完全一覧は docs/extension-points.json で、.ai/contracts-map.md にミラーリングされています。
コードサンプル — クイックスタート
「コードサンプル — クイックスタート」という見出しのセクション<?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() は、具象の Document を返します。この Document は PdfDocumentInterface を満たします。エンジン内部を差し替え可能な状態に保つため、独自サービスではインターフェイスを型ヒントに指定してください。
コードサンプル — 本番
「コードサンプル — 本番」という見出しのセクション<?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 は DocumentFactoryInterface を実装します。これはプロセスのライフタイムにわたる FontRegistryInterface と ImageRegistryInterface のシングルトンを保持し、使い捨ての各 Document に注入します。そのため、ワーカーは数千件のリクエストを処理する間、各フォントを 1 回だけ解析します。
エッジケースと注意点
「エッジケースと注意点」という見出しのセクション- コントラクトのみの型はコンパイルできますが、ランタイム上の実体はありません。まだどのクラスも実装していないため、
newをStreamingWriterInterfaceやCursorInterfaceに対して呼び出しても成功しません。これらは前方宣言された API として扱ってください。 - この
@stabilityPHPDoc タグは、単一の型に関する信頼できる情報源です。docs/extension-points.jsonは、集合に関する信頼できる情報源です。両者が食い違うとStabilityContractTestが失敗します。どちらか一方を編集して食い違いを隠さないでください。 experimentalは実際には不安定であるという意味ではなく、互換性の保証がより弱いという意味です。コントラクトに固定する前に、各コントラクトのbc_promiseフィールドを.ai/contracts-map.mdでお読みください。- ある
@internalクラスは、たとえ他のパッケージが技術的に参照できたとしても、決してコントラクトではありません。安定性テストは、マニフェストに現れるあらゆる@internal型を拒否します。 - ある
stableインターフェイスへのメソッド追加は、そのメソッドがデフォルト実装を伴って提供されない限り、実装者にとって破壊的変更です。エンジンは、既存のインターフェイスを拡張するのではなく、新しいインターフェイスを通じて機能を追加します。
パフォーマンス
「パフォーマンス」という見出しのセクションこの Contracts に対してプログラミングしても、測定可能なランタイムコストは加わりません。インターフェイスの型ヒントは、呼び出しごとではなくリンク時に解決されます。このページのワーカー例の performance_budget は、3 つのドキュメント全体で実時間 1500 ms、ピーク 64 MB です。最初のリクエストでのフォント解析が、その予算の大半を占めます。以降のリクエストはレジストリキャッシュを再利用し、コントラクトに起因する処理は 1 桁ミリ秒まで低下します。コストモデルはコントラクトのディスパッチごとに O(1) です。実際の処理は具象実装の中にあり、各ドメインページで説明しています。
セキュリティに関する注意
「セキュリティに関する注意」という見出しのセクションSPI はセキュリティ境界でもあります。HtmlSecurityPolicyInterface と ExternalResourcePolicyInterface は、信頼できない HTML がレンダラーに到達する前に、その挙動を制約するデフォルト拒否のコントラクトです。CryptoPolicyInterface は、署名と暗号化に対するアルゴリズムと鍵強度の選択を制御します。これらはコントラクトであるため、インテグレーターはエンジンをフォークすることなく、より厳格なポリシーを提供できます。セキュリティに関わるポリシーは、stable ティアに固定してください。experimental のポリシーコントラクトは、マイナーリリース間で形が変わる場合があります。署名およびセキュリティポリシーの各ドメインページに、完全な脅威モデルと規範的参照が記載されています。
この概要は直接的な規範的主張を行いません。各ドメインページが独自の citations ブロックをレンダリングします。署名コントラクトは、ISO 32000-2 §12.8(電子署名)および ETSI EN 319 142(PAdES ベースライン)に対応付けられます。PDF/A マネージャーは ISO 19005-4 に対応付けられます。節レベルの適合性表については、署名、セキュリティポリシー、抽出の各ページを参照してください。
商用コンテキスト
「商用コンテキスト」という見出しのセクションPro エディションと Enterprise エディションは、いくつかのコアコントラクトの背後にある本番コードを実装しています。LtvManagerInterface(長期検証)、PdfAManagerInterface(PDF/A の強制)、ハードウェアセキュリティモジュール(HSM)と遅延署名者、バーコードエンコーダー、そして埋め込みおよびベクトルインデックスのコントラクトです。Core はインターフェイスを公開して凍結し、Premium パッケージが実装を提供します。これにより、オープンソースエンジンは Apache-2.0 のまま保たれ、同時に商用デプロイには API を変更せずにそのまま導入できるアップグレードを提供します。
- コントラクト / ドキュメント — PDF ドキュメント、ファクトリー、レジストリのコントラクト。
- コントラクト / 署名 — 署名者、HSM、タイムスタンプ、LTV のコントラクト。
- コントラクト / セキュリティポリシー — 暗号、HTML、リソースポリシーのコントラクト。
- コントラクト / タイポグラフィ — フォントレジストリとテキスト前処理のコントラクト。
- コントラクト / 抽出 — インスペクター、PDF/A、埋め込み、e-invoice のコントラクト。
- Core — これらのコントラクトを満たす具象クラス。
- Event —
Contractsと並んで公開される、イベント SPI の対応物。