Навигация: аннотации, ссылки, закладки, действия и вложения
Модуль Navigation формирует интерактивный слой формата Portable Document Format (PDF). Он охватывает аннотации, ссылочные аннотации и Uniform Resource Locator (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молча нормализует враждебный ввод: недопустимый подтип заменяется значением по умолчанию, значок, не являющийся PDF-именем, заменяется значком по умолчанию, а некорректныеQuadPointsотбрасываются. Аннотация всё равно создаётся; проверяйте входные данные на стороне источника, если требуется строго сохранить их значения.LinkManager::preallocateAnnotationObjects()нужно выполнить до того, как Writer сериализует ссылки, иначе цели ссылок останутся неразрешёнными.Action::withNext()возвращает новое действие с присоединённой цепочкой; интерфейс поддерживает неизменяемое связывание в цепочку, а не изменение на месте.FileAttachment::writeAttachments()требует действующегоObjectRegistryот Writer. Если вызвать его изолированно, менеджер накопит намерения, но ничего не запишет, пока им не управляет Writer.AnnotationFlags— это неизменяемый набор флагов.with()/without()возвращают новый экземпляр; исходный остаётся без изменений.
Производительность
Заголовок раздела «Производительность»Накопление аннотаций, ссылок и закладок имеет сложность O(n) по числу элементов и не выполняет перекомпоновку. Стоимость встраивания файла-вложения определяется размером встраиваемых байтов, а не накладными расходами менеджера. Эталонная нагрузка по умолчанию укладывается в бюджет 1500 мс времени / 64 МБ пиковой памяти. Профиль воспроизводимости — structural: номера объектов и значение /ID в трейлере различаются между запусками. Два документа с одинаковыми навигационными намерениями структурно равны, но не идентичны побайтово.
Замечания по безопасности
Заголовок раздела «Замечания по безопасности»AnnotationManager рассматривает подтип аннотации, значок и QuadPoints как недоверенные. Он проверяет каждое значение по списку разрешённых или шаблону и заменяет недопустимое значение вместо того, чтобы записать его как есть. Это закрывает вектор инъекции PDF-имени. LinkManager::addUrlAnnotation() кодирует 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/.
См. также
Заголовок раздела «См. также»- Модуль Document
- Модуль Multimedia — объекты воспроизведения, запускаемые действием воспроизведения.
- Модуль Writer — сериализует навигационные структуры.
- Обзор соответствия
- Модель безопасности движка