Перейти к содержимому
getnextpdf.com

Pro редакция

Merge — глубокий справочник

Эта страница — справочник контрактного уровня для модуля NextPDF Pro Merge, NextPDF\Pro\Merge. SmartMerger собирает несколько входных документов в один и применяет улучшения Pro: консолидированное дерево закладок из меток отдельных вводов, дедупликацию на уровне всего документа, выбор диапазона страниц для каждого ввода и обнаружение внутренних ссылок. SemanticSplitter — сопутствующая точка входа для разбиения с учётом структуры. Эта страница описывает публичный API, контракт наблюдаемого поведения, границы ресурсов и режимы отказа. Ориентированная на задачи настройка и примеры находятся на странице возможности Merge.

Эта возможность поставляется в NextPDF Pro (nextpdf/pro) и активируется лицензионным конвертом уровня Pro. Развёртывание без этого права не загружает классы возможности. Сравнить редакции и получить лицензию.

Никакой флаг возможности времени выполнения не закрывает этот модуль. Классы Merge доступны всякий раз, когда nextpdf/pro установлен и лицензирован.

СимволПараметрыПоведение по умолчаниюВозвращаетБросает или завершается с ошибкойПримечания
SmartMerger::__construct()?PdfMerger $coreMerger = null, ?PdfSplitter $splitter = nullПринимает и игнорирует устаревший объединитель Core; аргумент null для splitter конструирует стандартный Pro splitter$coreMerger сохранён только для обратно совместимого конструирования
SmartMerger::merge()list<MergeInput> $inputs, SmartMergeConfig $config = new SmartMergeConfig()Сокращает диапазоны страниц, дедуплицирует целые вводы, делегирует базовую сборку, затем внедряет закладки и подсчитывает ссылки согласно конфигурацииSmartMergeResultInvalidArgumentException при пустом списке ввода; OverflowException, когда число вводов превышает maxInputs или ввод превышает maxBytesPerInputЕдинственная точка входа объединения
MergeInput::__construct()string $pdfData, list<PageRange> $pageRanges = [], string $label = ''Value-объект; пустой $pageRanges выбирает все страницыReadonly
MergeInput::hasPageRanges()True, когда ввод содержит хотя бы один диапазон страницbool
SmartMergeConfig::__construct()bool $consolidateBookmarks = true, bool $deduplicatePages = false, bool $rewriteLinks = true, int $maxInputs = 100, int $maxBytesPerInput = 100_000_000Value-объект, содержащий переключатели улучшений и границы ресурсовReadonly; дедупликация включается по выбору
SmartMergeConfig::default()Закладки и сканирование ссылок включены, дедупликация выключенаselfСтатическая фабрика
SmartMergeConfig::basic()Все улучшения выключены; только базовая конкатенацияselfСтатическая фабрика
SmartMergeResult::__construct()string $pdfData, int $totalPages, int $sourceCount, int $mergedSize, int $bookmarksAdded = 0, int $duplicatesRemoved = 0, int $linksRewritten = 0, list<string> $inputLabels = []Readonly-носитель для объединённых байтов и статистики консолидацииReadonly
SmartMergeResult::isValid()True, когда вывод начинается с заголовка %PDFboolТолько проверка заголовка
SmartMergeResult::hasOptimizations()True, когда удалён хотя бы один дубликат или подсчитана хотя бы одна ссылкаbool
SemanticSplitter::__construct()?PdfSplitter $splitter = nullАргумент null конструирует стандартный Pro splitterВнедрение через конструктор для тестирования
SemanticSplitter::splitByStructure()string $pdfData, float $headingFontThreshold = 14.0Обнаруживает операторы Tf размера заголовка как начала разделов и разбивает на этих границах; при отсутствии обнаруженной структуры возвращает один раздел на весь документSplitResultInvalidArgumentException, когда буфер пуст или не содержит заголовок %PDF; OverflowException, когда ввод превышает 100 MBОткатывается к разбиению по диапазонам страниц Core
public function __construct(
?PdfMerger $coreMerger = null,
?PdfSplitter $splitter = null,
)
public function merge(
array $inputs,
SmartMergeConfig $config = new SmartMergeConfig(),
): SmartMergeResult
public function __construct(
public string $pdfData,
public array $pageRanges = [],
public string $label = '',
)
public function hasPageRanges(): bool
public function __construct(
public bool $consolidateBookmarks = true,
public bool $deduplicatePages = false,
public bool $rewriteLinks = true,
public int $maxInputs = 100,
public int $maxBytesPerInput = 100_000_000,
)
public static function default(): self
public static function basic(): self
public function isValid(): bool
public function hasOptimizations(): bool
public function __construct(?PdfSplitter $splitter = null)
public function splitByStructure(
string $pdfData,
float $headingFontThreshold = 14.0,
): SplitResult

SmartMerger::merge() выполняет фиксированный конвейер, наблюдаемый извне следующим образом.

  1. Пустой список ввода вызывает InvalidArgumentException. Затем число вводов ограничивается maxInputs; превышение вызывает OverflowException.
  2. Каждый ввод перед использованием проверяется по размеру относительно maxBytesPerInput. Когда ввод объявляет диапазоны страниц, он сначала сокращается до выбранных страниц через Pro splitter, а затем вносит только эти страницы.
  3. Когда включён deduplicatePages, полная байтовая строка каждого входного документа получает отпечаток с помощью некриптографической функции xxh128. Ввод, байты которого в точности совпадают с более ранним вводом, отбрасывается. Дедупликация выполняется на уровне всего документа и с точностью до байта.
  4. Базовая сборка делегируется движку Pro PdfSplitter::mergeDocuments(), который перенумеровывает каждый ввод в одно непрерывное пространство объектов и выдаёт настоящую таблицу перекрёстных ссылок.
  5. Консолидация закладок применяется, когда включён consolidateBookmarks и хотя бы один ввод несёт непустую метку. Вставляется минимальный словарь /Outlines, связанный из каталога документа, с одной записью оглавления на каждый ввод в порядке объединения.
  6. Когда включён rewriteLinks, объединённый вывод сканируется на действия /S /GoTo, и сообщается их число.

SmartMergeResult сообщает объединённые байты плюс статистику. totalPages берётся из базового объединения. sourceCount — исходное число вводов, взятое до дедупликации. mergedSize — длина вывода в байтах. bookmarksAdded считает только вводы, предоставившие непустую метку. duplicatesRemoved считает отброшенные целые вводы. linksRewritten — обнаруженное число GoTo. inputLabels перечисляет разрешённые метки в порядке объединения. isValid() проверяет заголовок %PDF; hasOptimizations() истинно, когда удалён дубликат или подсчитана ссылка.

Каждая запись оглавления несёт метку ввода как /Title, экранированную как литеральная строка PDF согласно ISO 32000-2:2020 §7.3.4.2. Обратная косая черта сначала удваивается, скобки экранируются, именованные управляющие байты используют свои определённые последовательности, а любой оставшийся непечатаемый байт становится трёхзначным восьмеричным экранированием. Поэтому враждебная метка не может рассинхронизировать разделитель литеральной строки или внедрить структуру объектов. Вводы с пустой меткой получают заголовок-заполнитель Document N, с нумерацией от единицы.

Устаревший Core PdfMerger::merge() — намеренная заглушка с отказом «в закрытое состояние» в этом выпуске; SmartMerger никогда его не вызывает. Вместо этого базовое объединение проходит через Pro PdfSplitter::mergeDocuments(), поэтому объединённый файл несёт побайтово точную таблицу перекрёстных ссылок с одной записью на каждый косвенный объект согласно ISO 32000-2:2020 §7.5.4. Детерминизм следует документированному профилю Pro splitter: идентичные вводы и конфигурация дают стабильный поток байтов.

SemanticSplitter::splitByStructure() сканирует потоки содержимого страниц на операторы установки шрифта Tf со значением на уровне headingFontThreshold (по умолчанию 14.0) или выше и трактует каждую такую страницу как начало раздела. Границы преобразуются в диапазоны страниц и делегируются Pro PdfSplitter::split(). Когда граница не обнаружена, весь документ возвращается как один раздел. Ввод должен начинаться с %PDF и оставаться в пределах границы 100 MB.

  • Пустой список ввода завершается с InvalidArgumentException до какой-либо сборки.
  • Число вводов выше maxInputs (по умолчанию 100) или любой ввод выше maxBytesPerInput (по умолчанию 100 MB) завершается с OverflowException. Обе границы — намеренные отказы «в закрытое состояние», а не временные ошибки.
  • Дедупликация выполняется на уровне всего документа и с точностью до байта. Два ввода, которые рендерятся одинаково, но различаются хотя бы одним байтом, оба сохраняются, а duplicatesRemoved считает отброшенные целые вводы, несмотря на ориентированное на страницы имя deduplicatePages.
  • sourceCount отражает исходное число вводов, а не число документов после дедупликации.
  • Консолидация закладок срабатывает только тогда, когда хотя бы один ввод имеет непустую метку. При consolidateBookmarks, равном true, но при всех пустых метках объект /Outlines не записывается.
  • Внедряемые записи оглавления несут заголовки и древовидные связи /Parent, /Prev, /Next; они не встраивают явные назначения /Dest в этом выпуске.
  • Переписывание ссылок подсчитывает только действия /S /GoTo; оно не перенаправляет назначения через перенумерованные объекты. Трактуйте linksRewritten как число обнаружений.
  • Обнаружение в SemanticSplitter лексическое. Оно опирается на операторы размера шрифта Tf, поэтому страницы только с изображениями или необычно закодированные страницы не дают границ и возвращаются одним разделом на весь документ.

В этом модуле не выполняется никакой криптографической операции, поэтому нет поведения, специфичного для режима FIPS. Отпечаток содержимого xxh128, используемый для дедупликации, — некриптографический хеш обнаружения изменений и не несёт целостностного или доказательственного веса.

УтверждениеСтандартПункт
Консолидированные закладки записываются как словарь /Outlines, связанный из каталога документаISO 32000-2:2020§7.7.2
Базовое объединение выдаёт побайтово точную таблицу перекрёстных ссылок для каждого косвенного объектаISO 32000-2:2020§7.5.4
Заголовки записей оглавления экранируются как литеральные строки PDF, с обработкой обратной косой черты и скобокISO 32000-2:2020§7.3.4.2
Полное повторное разрешение ссылок между документамиНе поддерживается (только обнаружение GoTo)
Явные назначения оглавления по разделамНе выдаются в этом выпуске

Все пункты пересказаны; NextPDF не воспроизводит нормативный текст. Это утверждения о возможностях, а не сертификации; NextPDF не имеет сертификации и не предоставляет её.

  • Доступность внутри пакета Pro: SmartMerger, MergeInput, SmartMergeConfig, SmartMergeResult и SemanticSplitter с версии 2.2.0. Все актуальны в nextpdf/pro 3.1.0.
  • Базовое объединение делегируется Pro PdfSplitter::mergeDocuments(). Устаревший Core PdfMerger::merge() — заглушка с отказом «в закрытое состояние» в этом выпуске и никогда не вызывается.
  • Включайте deduplicatePages только тогда, когда вводы могут быть побайтово идентичными целыми документами; он не схлопывает почти дублирующиеся или перекодированные копии.
  • Используйте SmartMergeConfig::basic() для чистой конкатенации и ::default() для закладок плюс сканирования ссылок.
  • Перехватывайте OverflowException при объединении недоверенного ввода; границы числа и размера — намеренные отказы.
  • Предпочитайте Pro PdfSplitter напрямую для простого разбиения по диапазонам страниц; обращайтесь к SemanticSplitter только тогда, когда требуется разбиение на разделы по заголовкам.

Эта страница документирует только внешне наблюдаемое поведение и поддерживаемую публичную поверхность API. Внутренние пути пространств имён, вспомогательные классы, таблицы механизмов, имена файлов runbook и префиксы тикетов вне области рассмотрения.