跳转到内容
getnextpdf.com

Pro 版本

合并

NextPDF\Pro\Merge\SmartMerger 将多个 PDF 合并为一个,然后应用 Pro 增强:由各输入标签构建的整合书签树、 基于内容哈希的页面去重,以及逐输入的页码范围选择。基础文档组装通过 Pro 对象图合并引擎运行。它将每个输入重新编号至同一对象空间,并写出真实的交叉引用表。

此功能包含在 NextPDF Pronextpdf/pro)中,并通过 Pro 层级的授权信封激活。没有该授权的部署不会加载此功能的类。比较版本并获取授权

只要安装了 Pro 包,Merge 类即可用。没有运行时能力标记限制本模块。

Terminal window
composer require nextpdf/pro:^3

SmartMerger 接受一个 MergeInput 值对象列表。每个输入携带源 PDF 字节、一个可选的页码范围列表,以及一个可选标签。带页码范围的输入会在合并前被缩减到所选页面。合并后的文档由 Pro 对象图合并引擎产出,该引擎将每个输入重新编号至同一连续的对象空间, 并产出真实的交叉引用表;随后 Pro 层会添加所请求的增强。

SmartMergeConfig 控制这些增强:

  • 书签整合 为每个带标签的输入插入一个大纲条目, 指向该输入章节的起始处。这遵循 ISO 32000-2:2020 §7.7.2 中的文档目录 /Outlines 模型。
  • 页面去重 跨输入移除字节相同的重复页面, 按内容哈希比较。
  • 链接重写 在合并输出中扫描内部 GoTo 动作。

SmartMergeResult 报告合并后的字节以及统计信息:总页数、 源数量、输出大小、添加的书签数、移除的重复项数、检测到的链接数, 以及有序的输入标签。

合并 PDF 并非字节拼接:每个输入都携带自己的对象编号、交叉引用表与页面树,因此简单的拼接在任何符合规范的阅读器中都无法加载。因此,SmartMerger 将基础组装委派给 Pro 对象图引擎(PdfSplitter::mergeDocuments()),该引擎将每个输入重新编号至同一连续的对象空间,重建单一的页面树,并产出带有真实字节偏移的真实交叉引用表。Pro 增强—— 书签整合、去重与链接检测——随后叠加在该已验证的输出之上,而非重新实现组装。整文档去重与仅检测的链接处理是有意的范围边界, 可使合并在不受信任的输入上保持确定性且安全。

设计背景:PDF 文件剖析

  • 输入。 一个非空的 MergeInput 列表。空列表会抛出 InvalidArgumentException。输入数量与逐输入字节大小受 SmartMergeConfig 限制(maxInputsmaxBytesPerInput)。
  • 输出。 一个 SmartMergeResult。当输出以 %PDF 头开头时, isValid() 为 true。
  • 书签整合consolidateBookmarks 启用时,为每个带有非空标签的输入添加一个条目。
  • 去重 是可选启用的(deduplicatePages,默认关闭),并按内容哈希匹配整页,而非视觉上相似的页面。
  • 链接重写 在当前发行版中会检测并计数内部 GoTo 动作;它不会执行完整的跨文档目标重解析。请将 linksRewritten 视为一个检测计数。
  • 确定性。 对于相同的输入与配置,合并后的字节流是稳定的,受限于 Pro 合并引擎已记录的确定性 profile。
类型种类关键成员
NextPDF\Pro\Merge\SmartMergerfinal class__construct(?PdfMerger $coreMerger = null, ?PdfSplitter $splitter = null), merge(array $inputs, SmartMergeConfig $config = new SmartMergeConfig()): SmartMergeResult
NextPDF\Pro\Merge\MergeInputfinal readonly class__construct(string $pdfData, array $pageRanges = [], string $label = ''), hasPageRanges(): bool
NextPDF\Pro\Merge\SmartMergeConfigfinal readonly class__construct(bool $consolidateBookmarks = true, bool $deduplicatePages = false, bool $rewriteLinks = true, int $maxInputs = 100, int $maxBytesPerInput = 100_000_000), default(), basic()
NextPDF\Pro\Merge\SmartMergeResultfinal readonly classstring $pdfData, int $totalPages, int $sourceCount, int $bookmarksAdded, int $duplicatesRemoved, int $linksRewritten, array $inputLabels, isValid(): bool, hasOptimizations(): bool
<?php
declare(strict_types=1);
use NextPDF\Pro\Merge\MergeInput;
use NextPDF\Pro\Merge\SmartMerger;
$result = (new SmartMerger())->merge([
new MergeInput(file_get_contents('cover.pdf'), label: 'Cover'),
new MergeInput(file_get_contents('body.pdf'), label: 'Body'),
]);
echo $result->totalPages, " pages, ",
$result->bookmarksAdded, " bookmarks\n";
<?php
declare(strict_types=1);
use NextPDF\Pro\Merge\MergeInput;
use NextPDF\Pro\Merge\SmartMergeConfig;
use NextPDF\Pro\Merge\SmartMerger;
function assemblePacket(array $sections): string
{
$inputs = [];
foreach ($sections as $label => $bytes) {
$inputs[] = new MergeInput($bytes, label: (string) $label);
}
$config = new SmartMergeConfig(
consolidateBookmarks: true,
deduplicatePages: true,
rewriteLinks: false,
maxInputs: 50,
);
$result = (new SmartMerger())->merge($inputs, $config);
if (! $result->isValid()) {
throw new RuntimeException('merge produced invalid output');
}
return $result->pdfData;
}
  • 单个输入是有效的,会合并为该文档的一份归一化副本。
  • 去重按整页字节内容比较;仅在元数据或对象编号上有差异的页面不会被视为重复。
  • 对某个输入的页码范围选择会在合并排序之前应用。
  • linksRewritten 是一个被检测到的动作计数,而非每个跨文档链接目标都已被重新指向的保证。

成本主要由 Pro 合并引擎决定,并随总输入字节数与页数扩展。去重为每页增加一次内容哈希。 performance_budget front-matter 是逐次合并的参考。

输入数量与逐输入大小受 SmartMergeConfig 限制,以限制来自恶意输入的资源耗尽。合并不会执行内嵌的文档脚本。关于字节流解析加固,请参阅 Core 安全模型。

主张规范条款状态
通过 /Outlines 整合书签ISO 32000-2:2020 §7.7.2已验证(单元套件)
基于内容哈希的页面去重已验证(单元套件)
完整的跨文档链接重解析不支持(仅检测)

若只需不含 Pro 整合的基础拼接,开源 Core NextPDF\Document\PdfMerger 是受支持的独立路径。SmartMerger 不会委派给它;Pro 合并运行于其自有的对象图引擎之上。 参阅 /modules/core/document/

本模块执行结构性合并。它不执行法律保全组装、遮蔽或证据链监管打包;这些此处并不提供。

本页面仅记录可从外部观察到的行为以及受支持的公共 API 接口面。内部命名空间路径、辅助类、机制表、运行手册文件名以及工单前缀均不在范围内。