フォーム: AcroForm のインタラクティブフィールドとフラット化
Form モジュールは PDF のインタラクティブフォームを構築します。テキスト、チェックボックス、ラジオ、選択(リスト/コンボ)、ボタン、署名の各フィールドを作成し、parent/child の階層に整理したうえで、アピアランスストリームを持つ PDF オブジェクトとして書き出します。フォームを静的なページコンテンツへフラット化することもできます。
インストール
「インストール」という見出しのセクションcomposer require nextpdf/core:^3概念の概要
「概念の概要」という見出しのセクションPDF のインタラクティブフォームは AcroForm です。つまり、終端フィールドがページ上のウィジェット注釈と対応する、ドキュメントレベルのフィールド階層です。ISO 32000-2 §12.7 は、AcroForm ルートとフィールド階層を含むフォーム辞書とフィールド辞書を定義しています。このモジュールは、それをエンジン内でエンコードするためのものです。
主要なインターフェイスは FormFieldManager です。textField()、checkBox()、radioButton()、button()、signatureField() のビルダーを公開し、フィールドを追跡して、writeFields() でシリアライズします。ウィジェットごとに、§8.10 が要求する Form XObject のアピアランスストリーム(/Subtype /Form、/BBox)を出力します。FormField はフィールドの値オブジェクトです。FormFieldDictionaryBuilder はフィールドを対応する PDF 辞書へ変換し、型固有のエントリとフラグビット(テキスト、チェックボックス、選択、ボタン)を適用します。マネージャーと FormField は @since 1.0.0 です。辞書ビルダーは @since 1.1.0 です。
FormFieldHierarchy は parent/child のフィールドツリーをモデル化します。addChild()、getRootFieldNames()、getChildren()、getParent()、walkDepthFirst() ビジターを備えています。完全修飾フィールド名は、この階層をたどるドット区切りのパスであり、§12.7 がネストしたフィールドに対して規定するモデルです。
FormFlattener はフォームを静的なページコンテンツへレンダリングします。flatten() は FlattenResult を返すため、入力済みフォームをアーカイブ用に固定できます。FieldMDP と FieldMdpAction はフィールドロックの変換をモデル化します。署名済みドキュメントでは、名前付きのフィールド集合を以後の変更からロックできます。FieldMdpAction はロックのスコープを列挙します。その requiresFieldList() は、明示的なフィールドリストが必須となる場合を示します。FieldMDP は @since 2.0.0 です。
API サーフェス
「API サーフェス」という見出しのセクション| クラス | 主なメンバー | 役割 |
|---|---|---|
FormFieldManager | textField(), checkBox(), radioButton(), button(), signatureField(), addChildField(), getHierarchy(), writeFields() | フィールドビルダー+シリアライザー(@since 1.0.0) |
FormField | フィールドの値オブジェクト | AcroForm のフィールド 1 個(@since 1.0.0) |
FormFieldDictionaryBuilder | buildFieldDictionary(), applyTextFieldOptions(), applyCheckBoxOptions(), applyChoiceFieldOptions(), applyButtonOptions() | フィールドから辞書へのビルダー(@since 1.1.0) |
FormFieldHierarchy | addChild(), getRootFieldNames(), getChildren(), getParent(), walkDepthFirst() | Parent/child のフィールドツリー(@since 2.0.0) |
FormFlattener | flatten(array $fields, array $pages): FlattenResult | フォームの静的なコンテンツへのフラット化(@since 1.0.0) |
FieldMDP | toTransformParams() | フィールドロック(FieldMDP)の変換(@since 2.0.0) |
FieldMdpAction(enum) | requiresFieldList() | フィールドロックのスコープ(@since 2.0.0) |
完全な PHPDoc の表については、composer docs:generate-api-php -- --module=Form を実行してください。
コードサンプル — クイックスタート
「コードサンプル — クイックスタート」という見出しのセクションソース: examples/30-form-fields.php。
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Form\FormFieldManager;
$form = new FormFieldManager();
$form->textField(name: 'applicant_name', x: 50, y: 700, w: 200, h: 18);$form->checkBox(name: 'agree_terms', x: 50, y: 660, size: 12);$form->radioButton(name: 'plan', x: 50, y: 620, size: 12 /* + option set */);
// The Writer invokes $form->writeFields(...) during document serialization.コードサンプル — プロダクション
「コードサンプル — プロダクション」という見出しのセクション署名済みドキュメント用のフィールドセットを構築し、署名対象のフィールドを FieldMDP でロックします。
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Form\FieldMDP;use NextPDF\Form\FieldMdpAction;use NextPDF\Form\FormFieldManager;
$form = new FormFieldManager();$form->textField(name: 'contract_value', x: 50, y: 700, w: 160, h: 18);$form->signatureField(name: 'approver_sig', x: 50, y: 600, w: 200, h: 60);
// Lock only the named fields after signing.$lock = new FieldMDP( action: FieldMdpAction::Include, fields: ['contract_value'],);
$transformParams = $lock->toTransformParams();// $transformParams is attached to the signature's transform method by the signing layer.エッジケースと落とし穴
「エッジケースと落とし穴」という見出しのセクション- フィールド名は、
FormFieldHierarchyをたどる完全修飾のドット区切りパスです。同じ完全修飾名を持つ 2 つの終端フィールドは、ビューアー上では同一の論理フィールドになります。一意性の確保は呼び出し側の責任です。 FieldMdpAction::requiresFieldList()は、フィールドリストが必須となる場合を示します。必須リストを伴わないInclude/Excludeアクションは不正なロックです。フラグを確認してください。FormFlattener::flatten()は設計上、インタラクティブ性を失わせます。結果は静的なコンテンツです。後でインタラクティブ性が必要になる場合は、インタラクティブなソースを保持してください。- アピアランスストリームはウィジェットごとに出力されます。アピアランスを持たないフィールドは、ビューアー間でレンダリングが一貫しません。フィールドを省略するのではなく、マネージャーにアピアランスを生成させてください。
signatureField()はフィールドのプレースホルダーのみを作成します。実際の署名の生成は Security/署名レイヤーの役割であり、このモジュールの役割ではありません。
パフォーマンス
「パフォーマンス」という見出しのセクションフィールドの作成とシリアライズはフィールド数に対して O(n) であり、さらにウィジェットごとに Form XObject のアピアランスストリームが 1 個生成されます。フラット化のコストは、フィールド数ではなくレンダリングされるコンテンツ量に比例します。デフォルトの参照ワークロードは、1500 ms の実時間/64 MB のピーク予算内に収まります。再現性プロファイルは structural です。つまり、オブジェクト番号とトレーラーの /ID は実行ごとに変化します。同じフォームを持つ 2 つのドキュメントは構造的には等価ですが、バイト単位では同一になりません。
セキュリティに関する注記
「セキュリティに関する注記」という見出しのセクションフォームフィールドの値はユーザー入力です。このモジュールは PDF シリアライズのために文字列値をエスケープします(PdfStringEscaper)。そのため、フィールド値が PDF 文字列から抜け出して構造を注入することはできません。フォームが暗号化されている場合、フィールドの内容はドキュメントの AES-256 暗号化で保護されます。FieldMDP はセキュリティ上の制御です。つまり、名前付きのフィールドを署名後の変更からロックします。署名されたフィールド集合と一致しないフィールドロックは、その制御を損ないます。ロックのスコープは意図的に設定してください。入力済みフォームから取り出した値は、すべて信頼できない入力として扱ってください。エンジンのセキュリティモデルについては /modules/core/security/ を参照してください。
このモジュールが出力するフォーム構造は、ISO 32000-2 §12.7 のインタラクティブフォームモデル(AcroForm ルートとフィールド辞書、およびドキュメントのフィールド階層)に従います。ウィジェットごとのアピアランスは §8.10 に従い、Form XObject として出力され、src/Form/ 内にインラインで文書化されています。これらは tests/Unit/Form/ で検証される実装上の事実です。エンドツーエンドの PDF 2.0 適合性を表明するものではありません。ドキュメント全体の適合性は、/modules/core/conformance/ のオラクルおよびゴールデンスイートによって検証されます。
- Navigation モジュール — フィールドに対応するウィジェット注釈。
- Security モジュール — 署名と FieldMDP の信頼モデル。
- Accessibility モジュール — PDF/UA 向けのフォームフィールドのタグ付け。
- 適合性の概要