Pro редакция
Document — глубокий справочник
Краткий обзор
Заголовок раздела «Краткий обзор»Модуль Document предоставляет три сборочных примитива Pro: разбиение по диапазонам страниц, слияние нескольких документов и построение словаря PDF Portfolio (Collection). PdfSplitter извлекает диапазоны страниц в самостоятельные структурно-соответствующие PDF и объединяет целые документы в один файл с перенумерацией. PdfPortfolio строит словарь Collection, который представляет встроенные файлы с сортируемыми столбцами схемы. Каждая точка входа ограничивает размер ввода и число объектов от враждебного ввода.
Доступность и лицензирование
Заголовок раздела «Доступность и лицензирование»Эта возможность поставляется в NextPDF Pro (nextpdf/pro) и активируется лицензионным конвертом уровня Pro. Развёртывание без этого права не загружает классы возможности. Сравнить редакции и получить лицензию.
Публичная поверхность API
Заголовок раздела «Публичная поверхность API»Все типы модуля находятся в пространстве имён NextPDF\Pro\Document. PageRange и MergeResult — объекты-значения Core из NextPDF\Document.
| Символ | Параметры | Поведение по умолчанию | Возвращает | Бросает или завершается с | Примечания |
|---|---|---|---|---|---|
PdfSplitter::split() | string $pdfData, list<PageRange> $ranges, int $maxBytes = 100_000_000, int $maxRanges = 1000 | Строит один самостоятельный сегмент PDF на каждый диапазон | SplitResult | InvalidArgumentException при отсутствии заголовка %PDF; OverflowException при нарушении предела размера, числа диапазонов или замыкания | Проверки выполняются до любого разбора |
PdfSplitter::splitEvery() | string $pdfData, int $pagesPerSegment | Выводит смежные N-страничные диапазоны; последний сегмент может быть короче | SplitResult | InvalidArgumentException при $pagesPerSegment < 1 или отсутствии заголовка | Делегирует split() с предельными значениями по умолчанию |
PdfSplitter::extractPages() | string $pdfData, PageRange $range | Возвращает один диапазон как самостоятельные байты PDF | string | InvalidArgumentException при отсутствии заголовка; OverflowException при нарушении предела замыкания | На этом пути нет параметров-пределов |
PdfSplitter::mergeDocuments() | list<string> $pdfs, int $maxInputs = 100, int $maxBytesEach = 100_000_000 | Объединяет вводы по порядку в один PDF с перенумерацией | MergeResult | InvalidArgumentException при пустом списке или вводе не-PDF; OverflowException при нарушении предела числа, размера каждого ввода или замыкания | Начиная с 3.1.0; наивысшая версия ввода задаёт заголовок вывода |
SplitResult | readonly $segments, $ranges, $totalPages | Несёт сырые байты сегментов плюс метаданные источника | — | — | Объект-значение final readonly |
SplitResult::count() | — | Считает произведённые сегменты | int | — | — |
SplitResult::segment() | int $index | Возвращает байты одного сегмента | string | OutOfRangeException при выходе индекса за границы | Индекс с нуля |
PdfPortfolio::__construct() | string $viewMode = 'tile' | Проверяет режим просмотра при конструировании | — | InvalidArgumentException при режиме, отличном от tile, detail, hidden | — |
PdfPortfolio::addSchema() | PortfolioField $field | Добавляет столбец схемы | self | — | Текучий |
PdfPortfolio::addEntry() | PortfolioEntry $entry | Добавляет запись файла | self | — | Текучий |
PdfPortfolio::getSchema() | — | Возвращает накопленные поля схемы | list<PortfolioField> | — | — |
PdfPortfolio::getEntries() | — | Возвращает накопленные записи файлов | list<PortfolioEntry> | — | — |
PdfPortfolio::count() | — | Считает записи файлов | int | — | — |
PdfPortfolio::generateCollectionDictionary() | — | Выдаёт строку словаря Collection | string | — | Блоки схемы и сортировки появляются только при наличии полей |
PortfolioEntry | $filename, $data, $description = '', $mimeType = 'application/octet-stream', $customFields = [] | Неизменяемый объект-значение записи файла | — | — | size() возвращает длину данных в байтах |
PortfolioField | $name, PortfolioFieldType $type, $displayName = '', $order = 0, $visible = true | Неизменяемый объект-значение столбца схемы | — | — | effectiveDisplayName() откатывается к $name |
PortfolioFieldType | Строковый enum: Text, Date, Number, FileName, Description, Size, ModDate, CreationDate | Отображает каждый случай в PDF /Subtype через pdfSubtype() | string (S, D, N, F, Desc) | — | Случаи типа даты делят субтип D; числовые случаи делят N |
Сигнатуры точек входа:
public function split(string $pdfData, array $ranges, int $maxBytes = 100_000_000, int $maxRanges = 1000): SplitResult
public function mergeDocuments( array $pdfs, int $maxInputs = 100, int $maxBytesEach = 100_000_000,): MergeResultpublic function __construct( private readonly string $viewMode = 'tile',)
public function generateCollectionDictionary(): stringКонтракт поведения
Заголовок раздела «Контракт поведения»Разбиение и слияние делят один конвейер графа объектов:
- Ввод должен начинаться с заголовка
%PDF. Проверки размера и числа выполняются до разбора и возбуждаютOverflowExceptionпри нарушении. - Листовые страницы обнаруживаются сканированием маркеров объектов страниц; узлы дерева страниц исключаются из подсчёта.
- Парсер индексирует каждый несжатый косвенный объект с учётом потоков при поиске терминатора. Побеждает первое вхождение идентификатора объекта, поэтому переопределения из инкрементальных обновлений не применяются.
- Наследуемые атрибуты дерева страниц (
/Resources,/MediaBox,/CropBox,/Rotate) материализуются на каждую извлечённую страницу обходом её цепочки/Parent, так что сегменты самодостаточны. - Собирается транзитивное замыкание косвенных ссылок каждой страницы, исключая обратное ребро
/Parent, и перенумеровывается в свежее непрерывное пространство идентификаторов. - Сериализатор выдаёт заголовок, Catalog, дерево Pages, объекты страниц и объекты замыкания, затем таблицу перекрёстных ссылок с точными по байтам смещениями и
startxref, указывающий на ключевое словоxref. mergeDocumentsповторяет конвейер для каждого ввода в одно общее пространство идентификаторов. Наивысшая версия PDF среди вводов задаёт заголовок вывода. Это соответствующая стандарту замена отключённого сумматора Core, который остаётся закрытым при отказе.- Вывод детерминирован. Не выдаётся ни временных меток, ни случайных идентификаторов, поэтому одинаковый ввод даёт одинаковые байты.
Сборка Portfolio:
- Конструктор проверяет режим просмотра. Выдаваемый токен
/View—/T,/Dили/Hдля плитки, деталей и скрытого соответственно. generateCollectionDictionary()выдаёт/Type /Collection, токен/View, блок/Schemaпри наличии полей и директиву/Sortпо первому полю схемы, по возрастанию.- Каждое поле схемы выдаёт
/Subtype(изpdfSubtype()),/N(экранированное отображаемое имя),/O(порядок) и/V(видимость). - Имена полей очищаются до допустимых токенов имён PDF; несловесные символы становятся подчёркиваниями. Строковые значения экранируются как литеральные строки PDF.
- Записи файлов доступны через
getEntries()для встраивания слоем записи. Сам словарь Collection несёт только просмотр, схему и сортировку.
Граничные случаи и режимы отказа
Заголовок раздела «Граничные случаи и режимы отказа»- Диапазон, не совпавший ни с одной страницей, даёт минимальный односстраничный сегмент (MediaBox 612 x 792), а не ошибку.
- Документ без обнаружимых маркеров страниц считается за одну страницу.
- Страницы, хранящиеся внутри потоков объектов, не обнаруживаются; в извлечении участвуют только несжатые косвенные объекты.
- При наличии дублирующихся идентификаторов объектов используется ревизия с наименьшим смещением; более поздние ревизии инкрементальных обновлений игнорируются.
- Замыкание ссылок на сегмент ограничено 50 000 объектами; злонамеренно самоссылочный граф или граф с большим разветвлением возбуждает
OverflowException. - Пределы по умолчанию: 100 МБ ввода, 1000 диапазонов, 100 вводов слияния. Все настраиваются вызывающей стороной для каждого вызова.
splitEvery()отклоняет размер сегмента меньше 1 сInvalidArgumentException.SplitResult::segment()отклоняет индекс за границами сOutOfRangeException.- Два имени полей схемы, различающиеся только пунктуацией, очищаются до одного ключа словаря; более позднее поле молча затеняет более раннее в выдаваемой схеме.
- Этот модуль не выполняет криптографических операций; режим FIPS не меняет его поведения.
Соответствие
Заголовок раздела «Соответствие»Вывод сегментов и слияния следует модели объектов страниц ISO 32000-2; источник аннотирует соответствующие разделы. Внешне проверяемые утверждения:
- Раскладка трейлера, байтовое смещение
startxrefи терминатор%%EOFследуют ISO 32000-2:2020, §7.5.5 — referenceef0f2a4b563b84f81b3e6428612bc47c510d94fc8096849d339abf0f3247d845. - Значения
/Viewсловаря Collection (/T,/D,/H) следуют ISO 32000-2:2020, §12.3.5 — reference5cefaaeb40f3ff98e3aba135ac57c9424a05c43144c1b9b5156bfd4295e08ddd. - Записи полей Collection
/Subtype,/N,/Oи/Vследуют ISO 32000-2:2020, §12.3.5 (словарь поля коллекции) — reference6300fbfdc8a913a8dc6f6ae34eff99f2bd03c4313a77777cdd5a8dd856d9537a.
Эти утверждения описывают реализованную возможность, проверенную тестами модуля. Поддержка конструкции не является утверждением о соответствии, а соответствие не является сертификацией; NextPDF не имеет сторонней сертификации для этого модуля.
Заметки по разработке
Заголовок раздела «Заметки по разработке»- Все классы модуля —
final; типы результатов и объектов-значений —readonly. Типы сплиттера и Portfolio восходят к 1.9.0;mergeDocuments()добавлен в 3.1.0. PageRangeиMergeResult— типы Core, поэтому места вызова остаются переносимыми между редакциями.- Трейлеры сегментов несут только
/Sizeи/Root; не выдаётся ни файлового идентификатора/ID, ни словаря/Info. - Для рабочих процессов инкрементальных обновлений или подписания передавайте байты сегментов модулю Writer, а не редактируйте их на месте.
- Модуль не логирует содержимого документа.
Граница публикации
Заголовок раздела «Граница публикации»Эта страница документирует только внешне наблюдаемое поведение и поддерживаемую публичную поверхность API. Внутренние пути пространств имён, вспомогательные классы, таблицы механизмов, имена файлов runbook и префиксы тикетов вне области рассмотрения.