NextPDF Artisan 启动与发现
要点摘要
标题为“要点摘要”的章节Artisan 是一个纯粹的 PSR-4 函数库,没有 service provider、没有包(bundle),也没有 framework(框架)自动发现清单。它的类一旦可被自动加载,它就「启动」了;所谓发现机制就是 Composer 的 PSR-4 映射表,仅此而已。
发现机制如何运作
标题为“发现机制如何运作”的章节该包的 composer.json 声明了两个 PSR-4 根目录——NextPDF\Artisan\ → src/Artisan/,以及 NextPDF\Parser\ → src/Parser/。这里没有 extra.laravel、没有 Symfony bundle 类,也没有 CodeIgniter registrar。启动时不会扫描、注册或挂载任何东西。
集成点在 nextpdf/core 一侧。Document(通过 HasTextOutput concern)对外提供 writeHtmlChrome(),并会在运行期执行一次针对 NextPDF\Parser\PdfReader 与 NextPDF\Artisan\PageImporter 的 class_exists() 检查。当这两者都能通过自动加载器 resolve(解析)时,就能使用 Chrome 路径。当它们无法解析时,core 会抛出版面异常,而不是触发致命错误。因此,所谓「发现」就是:Artisan 的类是否已经挂到自动加载器上?这个问题由 Composer 回答——完全不涉及任何 framework 机制。
这是有意为之的设计。这个桥接是 core 引擎跨越包边界取用的一项能力,而不是由 framework 管理的服务。这样一来,Artisan 在 Laravel、Symfony、CodeIgniter、CLI 脚本或队列 worker 中都能以相同方式使用,因为这些都不是前置条件。
启动流程
标题为“启动流程”的章节这里没有启动内核(bootstrap kernel)、没有命令注册,也没有延迟 provider 阶段。第一次调用 writeHtmlChrome() 就是整个生命周期的入口点。
容器绑定
标题为“容器绑定”的章节Artisan 没有 DI 容器,也不会注册任何绑定。各组件都是通过构造函数注入组装的普通对象:创建一个 ChromeRendererConfig,将其传给 ChromeHtmlRenderer,并按需注入一个 PSR-3 logger 和一个自定义的 HtmlSecurityPolicyInterface。在宿主容器中,请自行将 ChromeHtmlRenderer 注册为单例——示例请见 /integrations/artisan/production-usage/.
无容器的服务解析
标题为“无容器的服务解析”的章节NextPDF 的部分能力(Premium 电子发票合约)通常通过 framework 容器解析。Artisan 也会在无容器环境中运行——CLI 工具、独立脚本、自定义执行器——因此它附带了 EInvoiceServiceFactory:
| 方法 | 返回值 | 何时为 null |
|---|---|---|
makeEmbedder() | EmbedderInterface(Pro 版) | 未安装 Pro 层 |
makeValidator() | ValidatorInterface(Enterprise 版) | 未安装 Enterprise 层 |
makeDefaultProfile() | ProfileInterface(EN16931,Pro 版) | 未安装 Pro 层 |
makeSchematronRunner() | SchematronRunnerInterface(Enterprise 版) | 未安装 Enterprise 层 |
每次调用都会返回一个 全新 的实例(一次性使用语义——embed 与 validate 调用各自拥有一个可变的 XML 解析(parse)上下文,不得共享状态)。这个工厂(factory)是为少数没有容器的场景提供的便利手段,而不是 service locator。建议做法仍然是在构造时组装对象,并将它们作为构造函数参数传入。这种「找不到就返回 null」的行为与 framework 封装包一致,因此同一份调用端代码无论是否安装 Premium 都能运行。来源:src/Artisan/EInvoiceServiceFactory.php;集成测试位于 tests/Integration/Artisan/EInvoiceServiceFactoryIntegrationTest.php。
配置解析顺序
标题为“配置解析顺序”的章节这里没有配置文件层叠机制。配置就是你传给 ChromeRendererConfig 的内容:
- 明确传入的构造函数参数,或者
- 通过
ChromeRendererConfig::fromArray()从宿主提供的数组创建(采用 snake-case 键;未设置的键会回退到构造函数默认值;chrome_binary只有在值为非空字符串时才会应用)。
解析后的配置在 renderer(渲染器)的整个生命周期内不可变。每个键的说明请见 /integrations/artisan/configuration 一节。
- 「这个桥接能被发现吗?」——如果
class_exists(\NextPDF\Artisan\PageImporter::class)为true,说明 Composer 的自动加载器已加载它;core 就会使用 Chrome 路径。 - 「它启动了吗?」——这里没有可能失败的启动过程;缺少的依赖包会在第一次调用
writeHtmlChrome()时以类型化异常的形式暴露,映射关系整理于 /integrations/artisan/troubleshooting/. - 无容器的 Premium 检查——
EInvoiceServiceFactory::makeEmbedder() === null表示未安装 Pro 层;开源渲染路径不受影响。
另请参阅
标题为“另请参阅”的章节- 集成指南:/integrations/artisan/integration/
- 概览:/integrations/artisan/overview/
- 配置:/integrations/artisan/configuration/
- 生产环境使用:/integrations/artisan/production-usage/
- 疑难解答:/integrations/artisan/troubleshooting/