导航:注解、链接、大纲、动作与附件
导航模块负责构建 PDF 的交互层:注解、链接与 URL 注解、文件大纲(书签)与目录、动作与触发链、页面转场,以及带有关联文件关系的内嵌文件附件。
composer require nextpdf/core:^3概念总览
标题为“概念总览”的章节ISO 32000-2 §12 定义了 PDF 的交互功能,包括注解、动作、目的地与文件大纲。本模块是引擎面向这一层的编码器,由一组累积意图的管理器类,以及一组由这些管理器产出的值对象构成。
AnnotationManager 是覆盖范围最广的接口。它可以加入文本、自由文本、线段、矩形、圆形、多边形、折线、墨迹,以及文字标记类注解(高亮、下划线)。它经过了安全加固:未知的注解子类型会退回到安全的默认值;不是有效 PDF 名称令牌的图标名称会被替换;文字标记的 QuadPoints 必须以八的倍数个浮点数传入,否则会被舍弃。这些处理属于 PDF 注入防御,而不是为了让验证更方便。LinkManager 负责处理内部链接、具名目的地与 URL 注解。它会预先配置注解对象,使 Writer 在序列化之前就能引用它们。
BookmarkManager 与 TocBuilder 负责构建导航层级。文件大纲就是查看器在侧边栏中显示的书签树;TocBuilder 则在页面上渲染目录,并可使用 FontMetrics 进行 leader/width 版面配置。OutlineAutoGenerator 会从文件结构推导出大纲。
Action 层级位于 NextPDF\Navigation\Action 之下,用于建模由触发器驱动的行为:GoTo(远程与内嵌)、launch、named、hide、表单的 reset/submit,以及设置可选内容状态。§13 的屏幕注解播放动作目前已推迟处理:它属于后续工作且尚未接入,因此请勿将它当作受支持的动作来依赖。Action::withNext() 会构建单一触发事件所执行的动作链。PageTransition 用于建模演示文稿转场。FileAttachment 会从路径或字节字符串内嵌文件,并以 AFRelationship(关联文件关系枚举)为其标记。它会返回一个 FileAttachmentResult,并通过 writeAttachments() 写出。核心管理器为 @since 1.0.0。动作层级为 @since 2.1.0。FileAttachment 构造函数与 AFRelationship 分别在 @since 1.8.0 / @since 1.1.0 推出。
API 接口
标题为“API 接口”的章节| 类 | 主要成员 | 角色 |
|---|---|---|
AnnotationManager | addAnnotation()、addFreeText()、addLine()、addSquare()、addCircle()、addPolygon()、addInk()、addHighlight()、addUnderline() | 具有注入安全输入处理的注解构建器(@since 1.0.0) |
LinkManager | addLink()、setLink()、setDestination()、addLinkAnnotation()、addUrlAnnotation()、preallocateAnnotationObjects() | 内部链接、具名目的地、URL 注解(@since 1.0.0) |
BookmarkManager | addBookmark()、hasBookmarks()、write() | 文件大纲(书签)树(@since 1.0.0) |
TocBuilder | addEntry()、hasEntries()、render()、getEntries() | 页面上的目录(@since 1.0.0) |
Action(接口) | subtype()、toDictionary()、withNext()、nextChain() | 触发动作+动作链(@since 2.1.0) |
PageTransition | toDict()、toInlineDict() | 简报页面转场(@since 1.2.0) |
FileAttachment | embedFile()、embedFileFromString()、hasAttachments()、getCount()、writeAttachments() | 内嵌文件附件(@since 1.0.0) |
AFRelationship(枚举) | toPdfName() | 关联文件关系(@since 1.1.0) |
AnnotationFlags | with()、without()、has()、toInt() | 不可变的注解标志集合(@since 1.2.0) |
执行 composer docs:generate-api-php -- --module=Navigation 以获取完整的 PHPDoc 表格。
程序码范例——快速上手
标题为“程序码范例——快速上手”的章节源代码:examples/12-bookmarks-and-toc.php 通过封装 BookmarkManager 的高级外观构建文件大纲。直接使用管理器:
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Navigation\BookmarkManager;
$bookmarks = new BookmarkManager();$bookmarks->addBookmark(title: 'Chapter 1', level: 0, pageIndex: 0);$bookmarks->addBookmark(title: '1.1 Overview', level: 1, pageIndex: 0);$bookmarks->addBookmark(title: 'Chapter 2', level: 0, pageIndex: 4);
if ($bookmarks->hasBookmarks()) { // The Writer calls $bookmarks->write(...) during catalog serialization.}程序码范例——正式环境
标题为“程序码范例——正式环境”的章节以明确的关联文件关系内嵌附件,并在文件定稿前检查结果。
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Navigation\AFRelationship;use NextPDF\Navigation\FileAttachment;
$attachments = new FileAttachment();
$attachments->embedFile( path: '/srv/invoices/INV-2026-0042.xml', description: 'Structured invoice source (Factur-X)', afRelationship: AFRelationship::Source,);
if ($attachments->hasAttachments()) { // writeAttachments() is invoked by the Writer with a live ObjectRegistry; // getCount() lets the application assert the expected attachment count. assert($attachments->getCount() === 1);}边界情况与陷阱
标题为“边界情况与陷阱”的章节AnnotationManager会静默规范化恶意输入:无效的子类型会变成默认值、非名称的图标会变成默认图标,而格式错误的QuadPoints会被舍弃。注解仍然会被生成;如果你需要这些输入被原样采用,请在上游验证它们。LinkManager::preallocateAnnotationObjects()必须在 Writer 序列化引用之前执行,否则链接目标会解析为空。Action::withNext()会返回一个附带动作链的新动作;此接口是为不可变链接而设计的,并非原地变更。FileAttachment::writeAttachments()需要 Writer 提供一个运行中的ObjectRegistry。单独调用管理器只会累积意图;在 Writer 驱动它之前,不会写出任何内容。AnnotationFlags是不可变的标志集合。with()/without()会返回新的实例;原本的实例不会变动。
注解、链接与书签的累积在项目数量上是 O(n),且不会重新排版。内嵌文件附件的成本主要由内嵌的字节大小决定,而非由管理器决定。默认参考工作负载落在 1500 毫秒墙钟时间/64 MB 峰值预算之内。可重现性配置文件是 structural:对象编号与尾段的 /ID 会在不同执行之间有所差异。两份具有相同导航意图的文件在结构上相等,但并非字节完全相同。
安全注意事项
标题为“安全注意事项”的章节AnnotationManager 将注解子类型、图标与 QuadPoints 视为不可信:每一项都会通过允许清单或样式进行验证,不良值会被替换,而不是直接写出。这封堵了一条 PDF 名称注入路径。LinkManager::addUrlAnnotation() 会将 URL 编码为链接动作。URL 的可信性由使用者方负责;恶意 URL 也是有效 URL,因此在加入目的地前请先清理它们。FileAttachment 会内嵌任意字节。请限制内嵌大小,并在附件来源来自使用者时将其视为不可信。请参阅 /modules/core/security/ 中的引擎威胁模型。
符合性
标题为“符合性”的章节本模块产出的结构遵循 ISO 32000-2 §12,即注解、动作、目的地,以及文件大纲层级。各项功能的条款参照(注解图标 §12.5.6.4、文字标记 QuadPoints §12.5.6.10、动作 §12.6)在 src/Navigation/ 中以内联方式记载,并由 tests/Unit/Navigation/ 进行验证。这些是实现事实,并非端到端 PDF 2.0 符合性声明。全文件符合性由 /modules/core/conformance/ 中所述的 oracle 与黄金测试套件验证。