Pro редакция
Form — глубокий справочник
Эта страница — глубокий справочник по модулю Pro Form. Она охватывает извлечение значений AcroForm, чтение и запись XFDF, привязку данных и извлечение данных XFA. Модуль потребляет значения NextPDF\Form\FormField, создаваемые считывателем форм Core, и добавляет поверх них сериализацию, разбор и привязку. Поддержка XFA ориентирована на данные: парсер структурирует пакеты template и datasets. Он не выполняет скрипты вычислений XFA и не рендерит динамические макеты XFA.
Доступность и лицензирование
Заголовок раздела «Доступность и лицензирование»Эта возможность поставляется в составе NextPDF Pro (nextpdf/pro) и активируется лицензионным конвертом уровня Pro. Развёртывание без этого права не загружает классы возможности. Сравнить редакции и получить лицензию.
Отдельного лицензионного флага для этой возможности нет. Это возможность редакции Pro.
Публичная поверхность API
Заголовок раздела «Публичная поверхность API»| Символ | Параметры | Поведение по умолчанию | Возвращает | Возбуждает или завершается ошибкой | Примечания |
|---|---|---|---|---|---|
FormDataExtractor::extract | list<FormField> $fields | Читает имя и значение каждого поля | XfdfData | — | Включает поля с пустым значением. |
FormDataExtractor::toArray | list<FormField> $fields | Строит строковую карту имя-значение | array<string, string> | — | Более поздний дубликат имени перезаписывает более ранний. |
FormDataExtractor::toXfdf | list<FormField> $fields, ?string $pdfHref = null | Делегирует XfdfWriter::fromFields | string (XFDF XML) | — | Удобный путь для экспорта одним вызовом. |
FormDataExtractor::extractNonEmpty | list<FormField> $fields | Пропускает поля, значение которых — пустая строка | XfdfData | — | — |
FormDataExtractor::getEmptyFieldNames | list<FormField> $fields | Перечисляет имена полей без заданного значения | list<string> | — | Дополнение к extractNonEmpty. |
XfdfWriter::fromFields | list<FormField> $fields, ?string $pdfHref = null | Собирает пары имя-значение, делегирует fromArray | string (XFDF XML) | — | — |
XfdfWriter::fromArray | array<string, string> $data, ?string $pdfHref = null | Оборачивает карту в XfdfData, делегирует | string (XFDF XML) | — | — |
XfdfWriter::fromXfdfData | XfdfData $data, ?string $pdfHref = null | Сериализует в XFDF; имена в точечной нотации вкладываются в иерархические элементы <field> | string (XFDF XML) | — | Удаляет управляющие символы, недопустимые в XML 1.0; см. контракт поведения. |
XfdfParser::parse | string $xfdfXml | Загружает XML с защитой от XXE и уплощает поля до точечной нотации | XfdfData | InvalidArgumentException | Предел ввода 10 MiB; принимает корни с пространством имён и без него. |
XfdfParser::parseFile | string $filePath | Разрешает путь, читает файл, делегирует parse | XfdfData | InvalidArgumentException | Отсутствующие, не-файловые или нечитаемые пути возбуждают исключение. |
XfaParser::parse | string $pdfData | Проверка маркера, извлечение XML, разбор пакетов | XfaFormData | InvalidArgumentException, XfaParseException | Отсутствие маркера /XFA возвращает пустой результат, а не ошибку. |
XfaParser::hasXfa | string $pdfData | Сканирует байты в поисках маркера /XFA | bool | — | Сканирование байтового маркера; совпадает любое вхождение токена. |
XfaParser::extractXfaXml | string $pdfData | Сканирование потоков на маркеры XFA, затем прямой поиск <xdp:xdp> | string (XFA XML или '') | RuntimeException (объявлено) | Сканирует не более первых 50 MiB ввода. |
XfaParser::parseXml | string $xml | Извлекает пакеты template и datasets, разбирает элементы <field> | XfaFormData | XfaParseException | Предел XML 10 MiB, проверяется до загрузки DOM. |
FormDataBinder::bind | list<FormField> $fields, XfdfData $data | Создаёт новые экземпляры FormField с привязанными значениями | FormDataBindResult | — | Оригиналы никогда не изменяются; флажки нормализуются к Yes/Off. |
FormDataBinder::fromXfdf | list<FormField> $fields, string $xfdfXml | Разбирает XFDF, затем привязывает | FormDataBindResult | InvalidArgumentException | Режимы отказа те же, что у XfdfParser::parse. |
FormDataBinder::fromArray | list<FormField> $fields, array<string, string> $data | Оборачивает карту в XfdfData, затем привязывает | FormDataBindResult | — | — |
FormDataBindResult | isFullyBound, hasNoUnmatchedKeys, boundCount, fieldCount; только для чтения fields, boundFieldNames, unmatchedDataKeys, unboundFieldNames | Неизменяемая диагностика привязки | по методу | — | isFullyBound требует ноль несопоставленных ключей и ноль непривязанных полей. |
XfdfData | hasField, getValue, count, isEmpty, getFieldNames, withField, withoutField, merge; только для чтения fields | Неизменяемый контейнер имя-значение | по методу | — | with* и merge возвращают новые экземпляры; merge предпочитает значения аргумента. |
XfaFormData | getField, hasField, count, fieldNames; только для чтения fields, templateXml, datasetsXml | Неизменяемый результат разбора XFA | по методу | — | Несёт необработанный XML пакетов template и datasets для кругового обмена. |
XfaFormField | только для чтения name, type, value, required, caption, options | Неизменяемая запись одного поля | — | — | type — одно из text, numeric, date, choice, button, signature. |
XfaPacket | варианты перечисления Template, Datasets, Config, LocaleSet, ConnectionSet, Form; xmlNamespace() | Перечисление пакетов на основе строк | string от xmlNamespace() | — | URI пространств имён следуют XFA Specification 3.3. |
public static function extract(array $fields): XfdfDatapublic static function toArray(array $fields): arraypublic static function toXfdf(array $fields, ?string $pdfHref = null): stringpublic static function extractNonEmpty(array $fields): XfdfDatapublic static function getEmptyFieldNames(array $fields): arraypublic static function fromFields(array $fields, ?string $pdfHref = null): stringpublic static function fromArray(array $data, ?string $pdfHref = null): stringpublic static function fromXfdfData(XfdfData $data, ?string $pdfHref = null): stringpublic static function parse(string $xfdfXml): XfdfDatapublic static function parseFile(string $filePath): XfdfDatapublic function parse(string $pdfData): XfaFormDatapublic function hasXfa(string $pdfData): boolpublic function extractXfaXml(string $pdfData): stringpublic function parseXml(string $xml): XfaFormDatapublic static function bind(array $fields, XfdfData $data): FormDataBindResultpublic static function fromXfdf(array $fields, string $xfdfXml): FormDataBindResultpublic static function fromArray(array $fields, array $data): FormDataBindResultИсключения
Заголовок раздела «Исключения»NextPDF\Pro\Form\Exception\XfaParseExceptionрасширяетRuntimeException— полезную нагрузку XFA невозможно разобрать вXfaFormData. Наследование сделано намеренно: существующие места вызова сcatch (RuntimeException $e)продолжают работать.- SPL
InvalidArgumentException— пустой, слишком большой, некорректный или не-XFDF ввод вXfdfParser; пустой ввод PDF вXfaParser::parse; нечитаемые пути вXfdfParser::parseFile.
Контракт поведения
Заголовок раздела «Контракт поведения»Извлечение AcroForm. FormDataExtractor обходит переданный вами список полей и читает имя и значение каждого поля. extract возвращает XfdfData; toArray возвращает простую строковую карту имя-значение. extractNonEmpty отбрасывает поля, значение которых — пустая строка; getEmptyFieldNames возвращает дополняющий список имён. Извлечение никогда не изменяет входные поля.
Запись XFDF. XfdfWriter создаёт документ, соответствующий структуре ISO 19444-1:2019. Вывод начинается с XML-объявления XFDF и корня xfdf в пространстве имён Adobe XFDF (http://ns.adobe.com/xfdf/) с xml:space="preserve". Ненулевой pdfHref порождает ссылку <f href="..."/> обратно на исходный PDF. Имена полей в точечной нотации (например, address.city) вкладываются в иерархическое дерево элементов <field>. Значения и атрибуты экранируют пять XML-метасимволов. Имена полей, значения и pdfHref дополнительно нормализуются для правильной оформленности: управляющие символы C0, запрещённые XML 1.0, удаляются, тогда как TAB, LF и CR сохраняются. Эта нормализация по своей природе с потерями, поэтому писатель всегда выдаёт правильно оформленный, повторно разбираемый XFDF независимо от байтов, переданных вызывающей стороной.
Чтение XFDF. XfdfParser принимает корни xfdf как с пространством имён, так и без него, и сопоставляет имя корня без учёта регистра, потому что некоторые производители выдают корневой элемент в верхнем регистре. Иерархические деревья <field> уплощаются обратно в имена в точечной нотации, поэтому запись и чтение совершают круговой обмен. Вся загрузка XML отключает доступ к сети и разрешение внешних сущностей. parseFile добавляет разрешение пути и проверки читаемости перед тем же разбором.
Привязка данных. FormDataBinder::bind сопоставляет ключи данных с именами полей. Поскольку FormField неизменяем, привязка создаёт новые экземпляры с обновлёнными значениями; оригиналы никогда не изменяются. Результат сообщает три диагностических набора: имена привязанных полей, ключи данных без соответствующего поля и поля, не получившие данных. Значения флажков нормализуются к модели состояния вкл/выкл из ISO 32000-2:2020, 12.7.5.2.3: без учёта регистра yes, true, 1 и on отображаются в Yes; любое другое значение отображается в Off.
Извлечение данных XFA. XfaParser::parse принимает необработанные байты PDF. Сначала он сканирует маркер /XFA; при отсутствии маркера возвращает пустой XfaFormData. Затем извлечение пробует две стратегии: сканирование блоков stream…endstream на индикаторы XFA XML, затем прямой поиск документа <xdp:xdp>. Единственный фрагмент xdp:xdp возвращается как есть; несколько фрагментов конкатенируются в синтезированный конверт xdp:xdp. parseXml извлекает пакеты template и datasets и разбирает каждый элемент <field> шаблона в XfaFormField: атрибут name обязателен, тип выводится из дочернего UI-элемента поля, флаг обязательности выводится из элемента validate с nullTest, установленным в error, а варианты выбора берутся из дочерних элементов items.
Поддержка XFA ориентирована на данные. Парсер структурирует пакеты template и datasets. Он не выполняет скрипты вычислений XFA, не рендерит динамические макеты XFA и не совершает круговой обмен каждым типом пакета. Проверьте парсер на вашем конкретном наборе документов, прежде чем полагаться на него.
Граничные случаи и режимы отказа
Заголовок раздела «Граничные случаи и режимы отказа»XfdfParser::parse('')возбуждаетInvalidArgumentException. Ввод больше 10 MiB возбуждаетInvalidArgumentExceptionс указанием предела.- Некорректный XML возбуждает
InvalidArgumentException, несущий собранные сообщения libxml. Правильно оформленный документ, корень которого неxfdf, возбуждает исключение и называет фактический корневой элемент. - Документ XFDF без элемента
<fields>разбирается в пустойXfdfData; это не ошибка. - Элементы полей без атрибута
nameпропускаются как при разборе XFDF, так и XFA. Поле XFDF без дочернего элемента<value>не даёт записи. XfaParser::parse('')возбуждаетInvalidArgumentException. PDF без маркера/XFAили тот, чей XFA XML не удаётся найти, возвращает пустойXfaFormDataвместо возбуждения исключения.hasXfa— сканирование байтового маркера: совпадает любой токен/XFAв файле, включая находящийся в неиспользуемом объекте. Последующий шаг извлечения решает, существует ли пригодный XML.- Извлечение XFA просматривает не более первых 50 MiB байтовой строки PDF; содержимое за этим пределом не сканируется.
- XFA XML больше 10 MiB возбуждает
XfaParseExceptionдо материализации какого-либо дерева DOM. Некорректный XFA XML возбуждаетXfaParseExceptionс сообщениями libxml. - Нормализация флажков никогда не пропускает нераспознанные значения; всё, что вне принятых форм «включено», отображается в
Off. - Удаление управляющих символов писателем происходит с потерями: байты C0, недопустимые в XML 1.0, в именах, значениях или
pdfHrefотбрасываются, чтобы вывод оставался правильно оформленным. TAB, LF и CR сохраняются. - Весь разбор XML отключает разрешение внешних сущностей и доступ к сети (защита от XXE).
- Этот модуль не выполняет криптографических операций; режим FIPS не меняет его поведения.
Соответствие
Заголовок раздела «Соответствие»| Поведение | Ссылка | Статус |
|---|---|---|
| Модель интерактивной формы / словаря поля | ISO 32000-2:2020, 12.7 | Согласовано (обосновано продуктом) |
Нормализация состояния вкл/выкл флажка (Yes/Off) | ISO 32000-2:2020, 12.7.5.2.3 | Согласовано; пункт процитирован в записи цитат этой страницы |
| Структура обмена данными XFDF | ISO 19444-1:2019 | Согласовано (обосновано продуктом) |
| Имена пакетов XFA и URI пространств имён | XFA Specification 3.3 | Согласовано (обосновано продуктом) |
Корпус RAG, доступный на момент написания, не включает ISO 19444-1:2019, XFA Specification или W3C XML 1.0, поэтому эти утверждения о согласованности обоснованы продуктом — из аннотаций исходного кода и тестов, а не процитированы по пунктам. Эти утверждения описывают возможности относительно упомянутых документов. NextPDF не имеет сертификации соответствия, и поддержка пункта не является заявлением о сертификации.
Заметки для разработки
Заголовок раздела «Заметки для разработки»- Каждая точка входа, кроме
XfaParser, статическая.XfaParserинстанцируем и без состояния; один экземпляр безопасно переиспользовать между документами. - Предполагаемый круговой обмен таков: считыватель форм Core создаёт значения
FormField;FormDataExtractorилиXfdfWriterсериализует их;XfdfParserчитает данные обратно;FormDataBinderприменяет их к списку полей. Иерархические имена переживают круговой обмен через точечную нотацию. - Используйте диагностику
FormDataBindResult(isFullyBound,unmatchedDataKeys,unboundFieldNames), чтобы обнаружить расхождение между файлом данных XFDF и изменённым шаблоном PDF, прежде чем принять заполнение. XfdfData— объект-значение:withField,withoutFieldиmergeвозвращают новые экземпляры. При коллизиях ключейmergeпредпочитает значения аргумента.XfaFormDataсохраняет необработанный XML пакетов template и datasets (templateXml,datasetsXml), поэтому вы можете постобработать пакеты, которые модель полей не охватывает.- Этот модуль сам не разбирает словари AcroForm из байтов PDF; он потребляет поля, создаваемые считывателем форм Core. Только
XfaParserработает с необработанным содержимым PDF.
Граница публикации
Заголовок раздела «Граница публикации»Эта страница документирует только внешне наблюдаемое поведение и поддерживаемую публичную поверхность API. Внутренние пути пространств имён, вспомогательные классы, таблицы механизмов, имена файлов руководств и префиксы тикетов вне области рассмотрения.