パイプラインモデル
Spec: ISO 32000-2, §7.5 ISO 32000-2 §7.5 Evidence: Code-backed
NextPDF のドキュメントは、不透明な単一ステップで生成されるわけではありません。少数の明示的なステージを順に通ります。意図を記録するファサード、その意図をモデルに変換するコンテンツ層、そしてそのモデルを準拠した PDF としてシリアライズするライターです。このページでは、その形と、なぜそのような形にしているのかを説明します。
これが重要な理由
「これが重要な理由」という見出しのセクションPDF ファイル形式自体は、ヘッダー、オブジェクト本体、クロスリファレンステーブル、トレーラーから成る階層構造です。ライターは、そのすべてを一貫して組み立てなければなりません。それを構築するエンジンが複雑に絡み合った単一の手続きであれば、どの変更もあらゆる出力を危険にさらします。そうなると、確信を得る唯一の方法はドキュメント全体をレンダリングして目視確認することになり、遅く、手遅れで、説得力にも欠けます。
明示的なパイプラインは、この状況を大きく変えます。各ステージには 1 つの役割と型付けされた境界があるため、変更について推論し、ファイルの最後だけでなく、その変更が触れるステージでテストできます。このアーキテクチャは、何よりもテスト可能性と拡張性のための意思決定です。
- 公開されているエントリーポイントは Document ファサード です。これは流暢で、一度だけ使用するワーカーセーフなビルダーであり、どのように シリアライズするかではなく、何を 求めているかを記録します。
- ファサードは、およそ 2 ダースの絞り込まれた 関心事トレイト(テキスト出力、描画、ページ、セキュリティ、ナビゲーションなど)へ委譲します。それぞれが 1 つの責務を持ち、1 つの巨大なクラスにはなりません。
- コンテンツは 2 つの経路のいずれかで届きます。直接描画(グラフィックスプリミティブ)または HTML/CSS エンジン です。どちらも同じ内部ドキュメントモデルを生成します。
- 専用の PDF ライター がそのモデルをシリアライズし、PDF 1.4 / 1.7 / 2.0 の戦略を選択します。有効なファイル構造の生成はここだけに存在し、ほかには存在しません。
- 長寿命の状態(フォントおよび画像のレジストリ)はプロセス単位のスコープを持ち、共有されます。リクエスト単位の状態(ドキュメント)は新規に作成され、再利用されません。境界が明示されていることが、ワーカーランタイムの安全性を支えます。
NextPDF のアプローチ
「NextPDF のアプローチ」という見出しのセクションこのモデルを最も明快に理解するには、呼び出しからバイト列までドキュメントを追うのがよいでしょう。
- Document facade Fluent, use-once builder; records intent via concern traits.
- Content production Direct drawing or the HTML/CSS engine — both build one document model.
- Document model Accumulated pages, content, and resources held as typed state.
- PDF writer Serialises the model; selects a PDF 1.4 / 1.7 / 2.0 strategy.
- Conforming PDF Header, object body, cross-reference table, trailer.
2 つの設計上の選択により、これは単なる図にとどまりません。
ファサードはモノリシックではなく、合成されています。 Document はすべての機能を自前で実装するのではなく、各領域を専用の関心事トレイト(テキスト出力、描画、ページ、セキュリティ、タイポグラフィ、ナビゲーション、トランザクションなど)へ委譲します。新しいドキュメントメソッドは、ファサード自体ではなく、その領域を所有するトレイトに属します。呼び出し対象のクラスは小さいまま保たれ、責務も分離されたままです。
ライターはファイル構造を排他的に所有します。 コンテンツ生成は、どの マークやオブジェクトが存在するかを決定します。ライターは、どのバージョン戦略を適用するかも含め、それらを どのように 有効な PDF ファイルにするかを決定します。この分離はアーキテクチャ上のルールとして強制されています。レイアウトおよびコンテンツのコードは最終的なファイル構造を出力せず、ライターはレイアウトに関する判断を行いません。この利点は、「出力は有効な PDF か?」という問いに対して、テストすべき場所がちょうど 1 つだけになることです。
ライフタイム境界は後付けではなく、モデルの一部です。フォントおよび画像のレジストリはプロセスの存続期間にわたって存在し、リクエスト間で共有されます。ドキュメント、そのレンダリングコンテキスト、ライターは、リクエストごとに作成され、破棄されます。ワーカーランタイムでは、この区別が安全な再利用とリクエスト間の破損を分けます。そのため、この点は規律に委ねるのではなく、アーキテクチャ内に明記されています。
エビデンスが示すこと
「エビデンスが示すこと」という見出しのセクションこのページは Evidence: Code-backed です。これらのステージは、コアリポジトリの実際の構造に対応しています。
- ファサードとその委譲は、
src/Core/Document.phpと、src/Core/Concerns/内の関心事トレイト(テキスト出力、出力、描画、ページ、セキュリティ、タイポグラフィ、ナビゲーション、トランザクションなど。それぞれが単一の責務を持ちます)に対応します。 - 2 つのコンテンツ経路は、HTML/CSS エンジン(
src/Html/)と直接描画(src/Graphics/)であり、どちらも内部モデルに供給します。 - シリアライズと PDF バージョン戦略は、
src/Writer/(PdfWriter.phpと、明示的な PDF 1.4 / 1.7 / 2.0 の戦略クラス)にあります。 - プロセス存続期間とリクエスト単位の境界は、アーキテクチャ概要に記録され、出荷済みのワーカーファクトリ例で実証されているワーカーセーフな設計です。この例では、リクエスト間で
FontRegistryとImageRegistryを共有しつつ、各Documentを新規に作成します。
出力の到達点は、形式によって決まっています。ライターの出力は、 に準拠して、ヘッダー、オブジェクト本体、クロスリファレンステーブル、トレーラーで構成されていなければなりません。 Spec: ISO 32000-2, §7.5 ISO 32000-2 §7.5 。その義務を 1 つのステージに集約することで、エンジンの残りの部分は、 ファイル構造の組み立てではなくコンテンツに集中し続けられます。
実践的な例
「実践的な例」という見出しのセクションファサードの役割は、意図を意図として読める形にすることです。コンテンツ経路とライターは、呼び出し側からは見えないままです。
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone(); // facade$doc->setTitle('Quarterly Report'); // metadata concern$doc->addPage(); // pages concern$doc->setFont('helvetica', 'B', 16); // typography concern$doc->cell(0, 12, 'Summary', newLine: true); // text-output concern$doc->writeHtml('<p>Generated in-process.</p>'); // HTML content path$doc->save(__DIR__ . '/report.pdf'); // writer stage各呼び出しは、それぞれ異なる関心事に到達します。2 つの異なるコンテンツ経路が、同じモデルに供給します。ちょうど 1 つのステージ、save() が、モデルをファイルのバイト列に変換します。呼び出し側は、クロスリファレンステーブルがどのように構築されるかを知る必要はありません。
よくある誤解
「よくある誤解」という見出しのセクションよくある誤読は、「パイプライン」が、Unix パイプのようにステージごとに配線するストリーミングプッシュ API を意味するというものです。しかし、そうではありません。ここでのパイプラインは、アーキテクチャ上の 分解です。単一の責務と型付けされた境界を持つステージから成ります。それでも、プログラミングの対象になるのは流暢なファサードです。これらのステージは、エンジンがどのように構築され、テストされるかを表すものであり、手作業で組み立てる伝送経路ではありません。
関連する誤りは、ファサードがエンジンそのもの である と思い込むことです。ファサードはエントリーポイントです。実際の処理は、関心事トレイト、2 つのコンテンツ経路、そしてライターに分散されています。この分散こそが、1 つの機能変更があらゆる出力を危険にさらさない理由です。
制限と境界
「制限と境界」という見出しのセクションこのページでは、パイプラインの 形 を説明しており、個々のステージの内部 API は説明しません。正確な関心事トレイトの一覧、ライター戦略の選択ルール、コンテンツモデルのフィールドは、この説明ではなく、コードとリファレンスによって定義されます。正確なトレイトの数は実装の詳細であり、モデルを変更せずに変わり得ます。このページでは、HTML エンジンの内部ステージ(別トピック)や、ライターのストリーミングおよびメモリの挙動(これも別トピック)は扱いません。構造に関する記述は、このページのレビュー日時点で正確です。権威ある情報源は、コアリポジトリの src/Core/、src/Html/、src/Graphics/、そして src/Writer/ です。
パイプラインモデルはエディション間で同一です。エディションは、新しいステージではなく、ステージ内に機能を追加します。
| Edition | Availability |
|---|---|
| Core | Core は、ファサード → コンテンツ → ライターの完全なパイプラインを実装します。 |
| Pro | Pro は、新しいステージではなく、既存のステージ内に機能を追加します。 |
| Enterprise | Enterprise は、新しいステージではなく、既存のステージ内に機能を追加します。 |
関連ドキュメント
「関連ドキュメント」という見出しのセクション- メモリとストリーミング — ライターステージがメモリを有限に保つ仕組み。
- HTML パイプライン — HTML コンテンツ経路の内部ステージ。
- あらゆる場所で厳格な型 — 各ステージを独立してテスト可能にする型付けされた境界。
- ファサード — 公開されている
Documentのエントリーポイント。意図を記録し、関心事トレイトへ委譲する、流暢で一度だけ使用するビルダー。 - 関心事トレイト — ファサードが合成する、絞り込まれた PHP トレイト。それぞれが単一の機能領域(テキスト出力、描画、ページ、セキュリティなど)を所有します。
- コンテンツ経路 — コンテンツがモデルに入る 2 つの方法のうちの 1 つ。直接描画または HTML/CSS エンジン。
- ドキュメントモデル — シリアライズ前に、ページ、コンテンツ、リソースをエンジン内部で型付けして蓄積したもの。
- ライターステージ — モデルを有効な PDF へシリアライズし、PDF 1.4 / 1.7 / 2.0 の戦略を選択するコンポーネント。
- ワーカーセーフ — プロセス存続期間の状態を安全に共有しつつ、リクエスト単位の状態は新規に作成され、再利用されないよう設計されていること。