Создание расширений: обзор публичного SPI
NextPDF предоставляет небольшой, продуманный набор публичных контрактов в пространствах имён NextPDF\Contracts и NextPDF\Event. Реализуйте эти контракты, чтобы добавлять шрифты, перехватывать текст, отслеживать жизненный цикл документа или подключать собственный сервер подписания, не форкая движок.
Установка
Заголовок раздела «Установка»composer require nextpdf/core:^3Концептуальный обзор
Заголовок раздела «Концептуальный обзор»NextPDF отделяет свой публичный интерфейс поставщика услуг (SPI) от внутреннего кода. SPI — это набор типов, которые вы можете реализовывать или за которыми можете наблюдать. Всё остальное приватно и может измениться без предупреждения.
Публичный SPI существует в трёх формах:
- Контракты реестров. Службы уровня процесса, которые вы заполняете перед созданием документов;
FontRegistryInterfaceиImageRegistryInterface— основные примеры. Зарегистрируйте ресурсы, и движок будет читать их оттуда. - Контракты стратегий. Точечные перехватчики, которые движок вызывает во время отрисовки.
TextPreprocessorInterfaceотвечает за перехват текста на этапе макета, аHtmlSecurityPolicyInterfaceуправляет доступом к возможностям HTML. Вы предоставляете поведение, а движок вызывает его. - Контракты подписания. Криптографические серверы.
SignerInterface,HsmSignerInterfaceиDeferredSignerInterfaceпозволяют вам отвечать за хранение ключа и формирование подписи. Движок строит структуру синтаксиса криптографических сообщений (CMS), а ваш код хранит ключ.
Отдельная система событий в NextPDF\Event, совместимая с рекомендацией PHP Standard Recommendation 14 (PSR-14), отвечает за наблюдение. События жизненного цикла позволяют реагировать на создание документа, новые страницы, загрузку шрифтов, подписание и запись результата. Поведение движка они не меняют.
У каждого контракта в исходном PHPDoc есть тег @stability: stable, experimental или deprecated. Этот тег и обещание обратной совместимости для конкретного контракта показывают, насколько серьёзных изменений можно ожидать. Полную политику смотрите в разделе Правила стабильности SPI.
Что можно расширять
Заголовок раздела «Что можно расширять»| Возможность | Публичный контракт | Стабильность |
|---|---|---|
| Регистрация и поиск шрифтов | NextPDF\Contracts\FontRegistryInterface | stable (с версии 1.7.0) |
| Кэширование и декодирование изображений | NextPDF\Contracts\ImageRegistryInterface | stable (с версии 2.0.0) |
| Перехват текста на этапе макета | NextPDF\Contracts\TextPreprocessorInterface | stable (с версии 1.9.0) |
| Управление возможностями HTML | NextPDF\Contracts\HtmlSecurityPolicyInterface | stable (с версии 3.1.0) |
| Подключение фабрики документов | NextPDF\Contracts\DocumentFactoryInterface | stable (с версии 1.7.0) |
| Синхронное подписание | NextPDF\Contracts\SignerInterface | stable (с версии 1.0.0) |
| Подписание с аппаратной поддержкой | NextPDF\Contracts\HsmSignerInterface | stable (с версии 1.0.0) |
| Отложенное и пакетное подписание | NextPDF\Contracts\DeferredSignerInterface | experimental (с версии 3.0.0) |
| Метки времени RFC 3161 | NextPDF\Contracts\TimestampProviderInterface | experimental (с версии 3.0.0) |
| Наблюдение за жизненным циклом | NextPDF\Event\* (совместимо с PSR-14) | stable-диспетчер; experimental-полезные нагрузки |
Что НЕ является публичным
Заголовок раздела «Что НЕ является публичным»Следующие типы являются внутренними. Не импортируйте их, не наследуйте от них и не зависьте от них:
- Любой класс за пределами пространств имён
NextPDF\ContractsиNextPDF\Event, если только в его PHPDoc нет тега@stability. - Конкретный код движка, включая парсер HTML, модуль записи, конвейер макета и сабсеттер шрифтов.
- Пакеты NextPDF Pro и NextPDF Enterprise. Их внутренние классы не входят в открытую поверхность с исходным кодом. Когда платная редакция поставляет реализацию SPI, используйте публичный контракт, а не её внутренний тип.
Поверхность API
Заголовок раздела «Поверхность API»Сгенерированная карта контрактов является эталонной и пересобирается из исходного кода для каждого выпуска. Считайте тег PHPDoc @stability в каждом файле интерфейса единственным источником истины. Используйте приведённую выше таблицу как вспомогательное средство при чтении.
Пример кода — быстрый старт
Заголовок раздела «Пример кода — быстрый старт»Зарегистрируйте шрифт, затем отследите момент его загрузки. Оба шага используют только публичные типы.
<?php
declare(strict_types=1);
use NextPDF\Contracts\FontRegistryInterface;use NextPDF\Event\Content\FontLoadedEvent;use NextPDF\Event\EventDispatcher;use NextPDF\Event\ListenerProvider;
/** @var FontRegistryInterface $fonts */$fonts->register('/srv/fonts/Inter-Regular.ttf', 'Inter');
$listeners = new ListenerProvider();$listeners->addListener( FontLoadedEvent::class, static function (FontLoadedEvent $event): void { \error_log("Font loaded: {$event->family} {$event->style}"); },);
$dispatcher = new EventDispatcher($listeners);Пример кода — рабочая среда
Заголовок раздела «Пример кода — рабочая среда»В долгоживущем воркере соберите реестры один раз при запуске, заблокируйте их и передайте общий диспетчер через фабрику документов.
<?php
declare(strict_types=1);
use NextPDF\Contracts\DocumentFactoryInterface;use NextPDF\Contracts\FontRegistryInterface;use NextPDF\Event\EventDispatcher;use NextPDF\Event\ListenerProvider;use Psr\Log\LoggerInterface;
final class DocumentBootstrap{ public function __construct( private readonly FontRegistryInterface $fonts, private readonly DocumentFactoryInterface $factory, private readonly LoggerInterface $logger, ) {}
public function warmup(): EventDispatcher { $this->fonts->warmup([ '/srv/fonts/Inter-Regular.ttf', '/srv/fonts/Inter-Bold.ttf', ]); $this->fonts->lock();
$listeners = new ListenerProvider(); $listeners->addListener( \NextPDF\Event\Security\SignatureAppliedEvent::class, fn (object $event): mixed => $this->logger->info('Signature applied'), );
return new EventDispatcher($listeners); }}Граничные случаи и подводные камни
Заголовок раздела «Граничные случаи и подводные камни»- Блокировка реестра. После
FontRegistryInterface::lock()методы изменения выбрасываютLogicException. Блокируйте реестр только после завершения прогрева. - Несоответствие стабильности. Контракт
experimentalможет измениться в минорном выпуске. Проверьте заявленную стабильность, прежде чем использовать контракт в рабочей среде. - Дисциплина пространств имён. Тип за пределами
NextPDF\ContractsилиNextPDF\Eventбез тега@stabilityявляется внутренним, даже если технически онpublic.
Производительность
Заголовок раздела «Производительность»SPI не создаёт накладных расходов, когда не используется. Если ни один слушатель не привязан к классу события, диспетчер событий сразу возвращает управление после единственной проверки hasListeners(). Реестры хранят чистые данные PHP и поддерживают прогрев при запуске, чтобы распределить задержку первого запроса.
Замечания по безопасности
Заголовок раздела «Замечания по безопасности»Контракты подписания — это поверхность, критичная для безопасности. HsmSignerInterface требует, чтобы закрытый ключ никогда не покидал аппаратную границу. Ваша реализация обязана соблюдать это требование. Контракт стороннего сервера подписания и его модель угроз смотрите в разделе контракт поставщика системы управления ключами (KMS).
Соответствие
Заголовок раздела «Соответствие»На этой обзорной странице нет нормативных утверждений. Соответствие для каждого контракта, включая усовершенствованные электронные подписи PDF (PAdES) и управление ключами, документировано на соответствующих страницах SPI.
Коммерческий контекст
Заголовок раздела «Коммерческий контекст»NextPDF Pro и NextPDF Enterprise предоставляют готовые к эксплуатации реализации нескольких контрактов подписания и проверки, включая подписание с поддержкой системы управления ключами. Ваш код зависит от публичного контракта, а редакция поставляет реализацию, поэтому код остаётся переносимым между редакциями.
Смотрите также
Заголовок раздела «Смотрите также»- Правила стабильности SPI
- Пользовательские шрифты
- Пользовательский макет и перехват текста
- Триггеры действий и слушатели событий
- Контракт поставщика KMS
Связанные контракты и модули
Заголовок раздела «Связанные контракты и модули»- Справочник по модулю контрактов — полная сгенерированная карта контрактов.
- Справочник по контрактам подписания —
SignerInterface,HsmSignerInterfaceиDeferredSignerInterface. - Справочник по контракту политики безопасности — подробности о
HtmlSecurityPolicyInterface. - Справочник по модулю событий — поверхность для наблюдения за жизненным циклом.
- Правила стабильности SPI — политика изменений для каждого тега
@stability. - Контракт поставщика KMS — контракт сервера подписания и модель угроз.
В глоссарии определены термины SPI, точка расширения, тег стабильности и обещание обратной совместимости; канонические определения смотрите в опубликованном глоссарии.