Ga naar inhoud

Form: interactieve AcroForm-velden en flattening

De Form-module maakt interactieve formulieren voor documenten in Portable Document Format (PDF). De module bouwt tekst-, checkbox-, radio-, keuze- (lijst/combo), knop- en handtekeningvelden, organiseert ze in een parent/child-hiërarchie, schrijft ze als PDF-objecten weg met appearance streams en kan het formulier flatten tot statische pagina-inhoud.

Terminal window
composer require nextpdf/core:^3

Een interactief PDF-formulier is de AcroForm: een veldhiërarchie op documentniveau waarvan de terminale velden gekoppeld zijn aan widget-annotaties op pagina’s. ISO 32000-2 §12.7 definieert dat formulier, de bijbehorende field dictionaries, de AcroForm-root en de veldhiërarchie. Deze module zet die structuren om voor de engine.

FormFieldManager is het primaire API-oppervlak. Het biedt de builders textField(), checkBox(), radioButton(), button() en signatureField() aan, houdt velden bij en serialiseert ze met writeFields(). Het genereert één Form XObject appearance stream voor elke widget (/Subtype /Form, /BBox), zoals §8.10 vereist. FormField is het value object van een veld. FormFieldDictionaryBuilder zet een veld om naar de bijbehorende PDF-dictionary en past typespecifieke entries en flag-bits toe voor tekst-, checkbox-, keuze- en knopvelden. De manager en FormField zijn @since 1.0.0. De dictionary builder is @since 1.1.0.

FormFieldHierarchy modelleert de parent/child-veldboom met addChild(), getRootFieldNames(), getChildren(), getParent() en een walkDepthFirst()-visitor. Een fully-qualified veldnaam is het door punten gescheiden pad door deze hiërarchie, conform het model voor geneste velden in §12.7.

FormFlattener rendert het formulier tot statische pagina-inhoud. flatten() retourneert een FlattenResult, zodat je een ingevuld formulier kunt bevriezen voor archivering. FieldMDP en FieldMdpAction modelleren de veldvergrendelingstransformatie. Een ondertekend document kan een benoemde set velden vergrendelen tegen verdere wijziging. FieldMdpAction somt de vergrendelingsreikwijdte op en requiresFieldList() geeft aan wanneer een expliciete veldenlijst verplicht is. FieldMDP is @since 2.0.0.

KlasseBelangrijkste membersRol
FormFieldManagertextField(), checkBox(), radioButton(), button(), signatureField(), addChildField(), getHierarchy(), writeFields()Veldbuilder en serializer (@since 1.0.0)
FormFieldvalue object van een veldEén AcroForm-veld (@since 1.0.0)
FormFieldDictionaryBuilderbuildFieldDictionary(), applyTextFieldOptions(), applyCheckBoxOptions(), applyChoiceFieldOptions(), applyButtonOptions()Builder van veld naar dictionary (@since 1.1.0)
FormFieldHierarchyaddChild(), getRootFieldNames(), getChildren(), getParent(), walkDepthFirst()Parent/child-veldboom (@since 2.0.0)
FormFlattenerflatten(array $fields, array $pages): FlattenResultFlattent het formulier tot statische inhoud (@since 1.0.0)
FieldMDPtoTransformParams()Veldvergrendelingstransformatie (FieldMDP) (@since 2.0.0)
FieldMdpAction (enum)requiresFieldList()Veldvergrendelingsreikwijdte (@since 2.0.0)

Voer composer docs:generate-api-php -- --module=Form uit om de volledige PHPDoc-tabel te genereren.

Bron: 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.

Bouw een veldenset voor een ondertekend document en vergrendel vervolgens de ondertekende velden met 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.
  • Een veldnaam is een fully-qualified, door punten gescheiden pad door FormFieldHierarchy. In een viewer zijn twee terminale velden met dezelfde fully-qualified naam hetzelfde logische veld. Je bent verantwoordelijk voor de uniciteit.
  • FieldMdpAction::requiresFieldList() geeft aan wanneer een veldenlijst verplicht is. Een Include/Exclude-actie zonder de vereiste lijst levert een misvormde vergrendeling op; controleer de flag.
  • FormFlattener::flatten() verwijdert bewust de interactiviteit. Het resultaat is statische inhoud. Bewaar de interactieve bron als je die later nog nodig hebt.
  • Appearance streams worden per widget gegenereerd. Een veld zonder appearance kan inconsistent worden weergegeven in verschillende viewers; laat de manager de appearance genereren in plaats van die weg te laten.
  • signatureField() maakt alleen de veldplaceholder aan. De Security- en ondertekeningslaag produceert de daadwerkelijke handtekening; deze module doet dat niet.

Het aanmaken en serialiseren van velden is O(n) in het aantal velden, plus één Form XObject appearance stream per widget. De kosten van flattening schalen met de gerenderde inhoud, niet met het aantal velden. De standaardreferentieworkload blijft binnen het budget van 1500 ms wall / 64 MB piek. Het reproduceerbaarheidsprofiel is structural: objectnummers en de trailer-/ID variëren tussen runs. Twee documenten met hetzelfde formulier zijn structureel gelijk, maar niet byte-identiek.

Waarden van formuliervelden zijn gebruikersinvoer. De module escapet stringwaarden voor PDF-serialisatie met PdfStringEscaper, zodat een veldwaarde niet uit de bijbehorende PDF-string kan breken en structuur kan injecteren. Wanneer een formulier versleuteld is, dekt de AES-256-versleuteling van het document ook de veldinhoud. FieldMDP is een beveiligingsmaatregel: het vergrendelt benoemde velden tegen wijziging na ondertekening. Een veldvergrendeling die niet overeenkomt met de ondertekende veldenset ondermijnt die maatregel; stel de vergrendelingsreikwijdte bewust in. Behandel elke waarde die uit een ingevuld formulier wordt geëxtraheerd als niet-vertrouwde invoer. Zie het beveiligingsmodel van de engine in /modules/core/security/.

De formulierstructuren die deze module genereert, volgen het model voor interactieve formulieren in ISO 32000-2 §12.7: de AcroForm-root, field dictionaries en de veldhiërarchie van het document. Appearances per widget worden conform §8.10 gegenereerd als Form XObjects en inline gedocumenteerd in src/Form/. tests/Unit/Form/ toetst deze implementatiefeiten. Die tests zijn geen verklaring van end-to-end PDF 2.0-conformiteit. Conformiteit van het volledige document wordt gevalideerd door de oracle- en golden suites in /modules/core/conformance/.