跳转到内容

NextPDF Symfony 启动与发现

内核(kernel)会注册 NextPdfBundle。包的 DI 扩展会载入 services.php,并将配置树(config tree)resolve(解析)为容器参数。随后,由一个编译器阶段(compiler pass)负责接线可选扩展与字体预热(font warmup)。

包的 composer.json 声明了自动注册提示:

{
"extra": {
"symfony": {
"bundles": {
"NextPDF\\Symfony\\NextPdfBundle": "all"
}
}
}
}

在 Symfony Flex 应用中,这会将 NextPDF\Symfony\NextPdfBundle 加入 config/bundles.php,并应用于每个环境(all)。如果未使用 Flex,请在 config/bundles.php 中手动添加此包。Symfony 官方文档正式说明了包注册模型(https://symfony.com/doc/current/bundles.html)。包类会在 PSR-4 前缀 NextPDF\Symfony\ 下自动加载,并映射到 src/Symfony/。PSR-4 自动加载器会将命名空间前缀映射到该基目录(PSR-4 §2)。

以下启动顺序已根据包的源代码核验:

  1. 内核注册包。 Kernel::registerBundles() 会读取 config/bundles.php,并创建 NextPDF\Symfony\NextPdfBundle 的实例;该类继承自 Symfony\Component\HttpKernel\Bundle\Bundle
  2. 包构建。 NextPdfBundle::build() 会先调用父类,然后注册一个编译器阶段:OptionalExtensionPassNextPdfBundle::getPath() 会返回包的根目录。
  3. 扩展载入。 DI 扩展 NextPDF\Symfony\DependencyInjection\NextPdfExtension(别名 nextpdf)会执行 processConfiguration(),并依据 Configuration 处理配置。它会将解析后的值设为 nextpdf.* 容器参数,然后通过 PhpFileLoader 载入 config/services.php
  4. 必需扩展防护。 NextPdfExtension::load() 会在末尾断言 ext-mbstringext-zlib 均存在;否则提前失败。
  5. 编译器阶段执行。 在容器编译期间,OptionalExtensionPass::process() 会在 PdfFactory 上设置扩展可用性标志,按需注册签名器与 TSA 客户端,并调度字体注册表的预热与锁定。
  6. 容器编译并缓存。 Symfony 会写出编译后的容器。cache:warmup 会在流量到达前先执行此步骤。

此包只注册一个阶段 NextPDF\Symfony\DependencyInjection\Compiler\OptionalExtensionPass,并在 NextPdfBundle::build() 中加入。它会在默认(优化前)阶段组中执行。该阶段执行四个步骤。每个步骤都有条件防护;如果输入不存在,就不会执行任何操作:

  • 扩展标志 — 向 PdfFactory 定义加入 setArtisanAvailable(...)setProAvailable(...) 方法调用。这些值来自编译期对 Artisan 浏览器工厂(factory)和 Pro PDF/A 类进行的 class_exists 探测。
  • 签名器注册 — 当 nextpdf.signature 存在、enabled 为 true 且已设置证书时,会为基准 B-B 配置文件注册证书信息工厂和签名器服务。
  • TSA 客户端 — 当 nextpdf.tsa 设有 URL 时,会注册 TSA 客户端服务。
  • 字体预热 — 当 nextpdf.preload_fonts 非空时,会向字体注册表定义加入 warmup()lock() 方法调用。

config/services.php 定义了这些服务。文档服务 nextpdf.document(别名为 NextPDF\Contracts\PdfDocumentInterfaceNextPDF\Core\Document)是 非共享 的:每次解析都会返回一份全新文档,这是 PSR-11 明确允许的;连续对同一个 id 调用 get() 可能返回不同的值(PSR-11 §1.1.2)。字体注册表是共享的,并在预热后锁定。图像注册表是共享的,并标记为 kernel.reset。完整表格请见 /integrations/symfony/configuration/.

  1. 来自 Configuration 的内置默认值(getConfigTreeBuilder())。
  2. 来自 config/packages/nextpdf.yaml 的应用程序覆盖,以及 config/packages/<env>/ 下的环境覆盖。
  3. Symfony 会解析 %kernel.*% 参数 placeholder(占位符)。例如,fonts_path 默认为 %kernel.project_dir%/resources/fonts
  4. NextPdfExtension::load() 会将合并后的结果写入 nextpdf.* 容器参数,供 services.php 与编译器阶段使用。

无效值会在步骤 1–2 触发 Symfony InvalidConfigurationException 并失败。

Terminal window
php bin/console debug:container nextpdf
php bin/console debug:config nextpdf
php bin/console cache:clear

第一个命令会列出已注册的服务。第二个命令会打印合并后的配置。第三个命令会重建容器,并重新执行编译期的扩展探测。

每一行都是本页提出的规范性主张,并固定到受控 SDO 语料库中的完整 64 位十六进制 reference_id。Provenance(来源信息,含语料库清单与检索传输)存放在 _sidecars/rag-citations.yaml

规范条款参考 ID(reference_id)主张
PSR-11psr_11_container#1.1.2.p3.b容器解析可能每次调用都不同
PSR-4psr_4_autoload#x1.x2.p5命名空间前缀到基目录的映射
  • /integrations/symfony/integration/ — 端到端接线参考。
  • /integrations/symfony/install/ — 安装与注册。
  • /integrations/symfony/configuration/ — 完整配置树与服务表。
  • /integrations/symfony/overview/ — 功能摘要。