Pro 版本
合并
NextPDF\Pro\Merge\SmartMerger 将多个 PDF 合并为一个,然后应用
Pro 增强:由各输入标签构建的整合书签树、
基于内容哈希的页面去重,以及逐输入的页码范围选择。基础文档组装通过 Pro 对象图合并引擎运行。它将每个输入重新编号至同一对象空间,并写出真实的交叉引用表。
可用性与授权
标题为“可用性与授权”的章节此功能包含在 NextPDF Pro(nextpdf/pro)中,并通过 Pro 层级的授权信封激活。没有该授权的部署不会加载此功能的类。比较版本并获取授权。
只要安装了 Pro 包,Merge 类即可用。没有运行时能力标记限制本模块。
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限制(maxInputs、maxBytesPerInput)。 - 输出。 一个
SmartMergeResult。当输出以%PDF头开头时,isValid()为 true。 - 书签整合 在
consolidateBookmarks启用时,为每个带有非空标签的输入添加一个条目。 - 去重 是可选启用的(
deduplicatePages,默认关闭),并按内容哈希匹配整页,而非视觉上相似的页面。 - 链接重写 在当前发行版中会检测并计数内部
GoTo动作;它不会执行完整的跨文档目标重解析。请将linksRewritten视为一个检测计数。 - 确定性。 对于相同的输入与配置,合并后的字节流是稳定的,受限于 Pro 合并引擎已记录的确定性 profile。
公共 API 接口面
标题为“公共 API 接口面”的章节| 类型 | 种类 | 关键成员 |
|---|---|---|
NextPDF\Pro\Merge\SmartMerger | final class | __construct(?PdfMerger $coreMerger = null, ?PdfSplitter $splitter = null), merge(array $inputs, SmartMergeConfig $config = new SmartMergeConfig()): SmartMergeResult |
NextPDF\Pro\Merge\MergeInput | final readonly class | __construct(string $pdfData, array $pageRanges = [], string $label = ''), hasPageRanges(): bool |
NextPDF\Pro\Merge\SmartMergeConfig | final 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\SmartMergeResult | final readonly class | string $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 | 已验证(单元套件) |
| 基于内容哈希的页面去重 | — | 已验证(单元套件) |
| 完整的跨文档链接重解析 | — | 不支持(仅检测) |
Core 回退/替代方案
标题为“Core 回退/替代方案”的章节若只需不含 Pro 整合的基础拼接,开源 Core
NextPDF\Document\PdfMerger 是受支持的独立路径。SmartMerger
不会委派给它;Pro 合并运行于其自有的对象图引擎之上。
参阅 /modules/core/document/。
Enterprise 边界说明
标题为“Enterprise 边界说明”的章节本模块执行结构性合并。它不执行法律保全组装、遮蔽或证据链监管打包;这些此处并不提供。
发布边界
标题为“发布边界”的章节本页面仅记录可从外部观察到的行为以及受支持的公共 API 接口面。内部命名空间路径、辅助类、机制表、运行手册文件名以及工单前缀均不在范围内。