NextPDF Laravel 集成概览
此 nextpdf/laravel 包将 NextPDF PDF 引擎接入 Laravel 12 应用,并为你注册容器绑定。它提供一个 Pdf facade、一个 PdfResponse HTTP 辅助类,以及一个可排入队列的 GeneratePdfJob。Laravel 会自动发现该包,因此你无需手动注册。
composer require nextpdf/laravelComposer 版本约束为 nextpdf/core: ^3.0 || ^5.2。此包还需要 laravel/framework: ^12.0 与 php: >=8.4 <9.0。完整步骤,包括配置发布与可选扩展,请参见 /integrations/laravel/install/.
概念说明
标题为“概念说明”的章节此包位于 Laravel 服务容器与框架无关的 NextPDF core 之间,承担一层很薄的适配职责。它不会重新实现 PDF 生成功能,而是将 core 的 NextPDF\Core\Document 模型适配到 Laravel 的生命周期、配置、队列与 HTTP 层。
下图展示了一个请求如何从你的应用代码出发,经由此包,最终进入共享的 core 注册表。
自动加载映射只包含一条 PSR-4 条目。PSR-4 是 PHP 自动加载的标准建议,其中前缀 NextPDF\Laravel\ 映射到 src/Laravel/。在 PSR-4 中,命名空间前缀对应一个基准目录,剩余类名再映射到该目录下的文件路径(PSR-4 §3)。此前缀下有四个正式提供的类:
NextPDF\Laravel\NextPdfServiceProvider— 注册绑定并发布配置。NextPDF\Laravel\Facades\Pdf— 一个静态 proxy(代理),会从容器 resolve(解析)出一个全新的 document。NextPDF\Laravel\Http\PdfResponse— 一个工厂,用于生成 inline、下载与流式 PDF 响应,并附带一组固定的安全标头。NextPDF\Laravel\Jobs\GeneratePdfJob— 一个可排入队列的 job,会在 worker 上创建并存储 PDF。
此服务提供者实现了 DeferrableProvider,因此只有当你解析其中一个已声明的条目时,它才会注册绑定。这种延迟机制让框架启动路径保持轻量。该提供者的 provides() 方法列出延迟加载的条目,容器会读取这份清单,并将每个键映射回该提供者。
解析遵循容器契约:只要绑定存在,解析该标识符就会返回已注册的条目。PSR-11 是 PHP 容器互操作性的标准建议,它指出,对同一个标识符连续调用两次 get(),可能会因绑定策略不同而返回不同的值(PSR-11 §1.1.2)。NextPDF 有意依赖这项行为。注册表是单例,因此每次解析都返回同一个实例;document 则采用工厂绑定,因此每次解析都返回一个全新的实例。完整的绑定生命周期表,请参见 /integrations/laravel/boot-and-discovery/.
此架构面向长生命周期 worker,例如 Octane、RoadRunner 与 Swoole。font registry 是进程生命周期内的单例:包只会预热一次并将其锁定,因此任何请求都无法修改共享的字体状态。image registry 也是进程生命周期内的单例,配有一个有界的最近最少使用(LRU)缓存。由于包始终通过 DocumentFactory 全新创建 document,因此每个请求的可变状态绝不会泄漏到其他请求。
API 接口
标题为“API 接口”的章节| 类 | 公开入口点 | 返回 | 用途 |
|---|---|---|---|
NextPdfServiceProvider | register()、boot()、provides() | void / array | 容器绑定、配置发布、延迟条目清单 |
Facades\Pdf | 静态 proxy(addPage()、cell()、save() 等) | static / mixed | 每次调用都会解析出一个 PdfDocumentInterface 实例 |
Http\PdfResponse | inline()、download()、streamInline()、streamDownload() | Response / StreamedResponse | 带有 OWASP 标头的 HTTP 响应 |
Jobs\GeneratePdfJob | dispatch()、handle()、then()、catch()、failed() | PendingDispatch / void / self | 排入队列的 PDF 生成 |
提供者绑定的容器键如下:
| 键 | 生命周期 | 解析为 |
|---|---|---|
NextPDF\Contracts\FontRegistryInterface(别名 FontRegistry) | 单例,已锁定 | NextPDF\Typography\FontRegistry |
NextPDF\Graphics\ImageRegistry | 单例,有界 LRU | ImageRegistry |
NextPDF\Contracts\DocumentFactoryInterface(别名 DocumentFactory) | 单例 | NextPDF\Core\DocumentFactory |
Psr\Http\Client\ClientInterface | 单例 | SecurityAwareHttpClient,包裹 CurlHttpClient |
NextPDF\Security\Timestamp\TsaClient | 作用域 | TsaClient,或在未配置 TSA URL 时为 null(即没有 TSA 客户端) |
NextPDF\Contracts\SignerInterface | 工厂 | DigitalSigner,或在停用签署时为 null(即未启用签署) |
NextPDF\Contracts\PdfDocumentInterface(别名 nextpdf) | 工厂 | NextPDF\Core\Document |
NextPDF\Contracts\EInvoice\{Embedder,Validator,Profile,SchematronRunner}Interface | 工厂 | 仅在安装了 nextpdf/premium 时才会解析 |
代码示例 — 快速上手
标题为“代码示例 — 快速上手”的章节<?php
declare(strict_types=1);
use NextPDF\Laravel\Facades\Pdf;
Pdf::addPage();Pdf::cell(0, 10, 'Hello from Laravel', newLine: true);Pdf::save(storage_path('app/hello.pdf'));以 controller 为上下文、可直接运行的示例,请参见 /integrations/laravel/quickstart/.
代码示例 — 生产环境
标题为“代码示例 — 生产环境”的章节生产环境的写法是从容器解析 document 契约,而非通过 facade;这样调用点更明确,也更易于测试。完整的 controller 示例(包含依赖注入(DI)与错误处理)请参见 /integrations/laravel/production-usage/.
<?php
declare(strict_types=1);
use NextPDF\Contracts\PdfDocumentInterface;use NextPDF\Laravel\Http\PdfResponse;
$document = app(PdfDocumentInterface::class);$document->addPage();$document->cell(0, 10, 'Invoice', newLine: true);
return PdfResponse::download($document, 'invoice.pdf');边界情况与陷阱
标题为“边界情况与陷阱”的章节- 此提供者采用延迟加载,因此解析一个不相关的容器键并不会启动 NextPDF。只有当你请求其中一个
provides()条目时,这些绑定才会出现。 SignerInterface与TsaClient在你尚未配置签署或时间戳机构时,按设计会解析为null。你的代码必须对结果进行 null 检查,不要假设实例一定存在。- e-invoice 契约绑定一律会注册,但它们只会解析到 Premium 的具体实现,而这些实现只有在安装了
nextpdf/premium时才存在。在没有 Premium 的情况下解析它们会引发 class-not-found 错误,且错误出现在首次解析时,而非启动时。 - 此 facade 每次解析都会返回一个全新的 document。假设同一个请求中有两次
Pdf::静态调用,并且两次调用之间执行了Pdf::clearResolvedInstances():这两次调用会操作不同的 document。
提供者注册以 O(1) 时间完成。此提供者只绑定闭包,不构造重量级对象,因此构造成本会延迟到首次解析时才发生。font registry 预热以 O(f) 时间完成,其中 f 是预加载的字体文件数量,并且每个 worker 进程只执行一次。这样的时机安排能在长生命周期 worker 中摊销首次请求延迟。本概览的单页内存预算记录在 front-matter 字段 performance_budget 中。
安全性备注
标题为“安全性备注”的章节PdfResponse 会应用一组来自开放全球应用安全项目(OWASP)的固定安全标头。这些标头包括 X-Content-Type-Options: nosniff、X-Frame-Options: DENY、Content-Security-Policy: default-src 'none'、X-Robots-Tag,以及 Referrer-Policy: no-referrer。GeneratePdfJob 会在 worker 端验证输出路径,这项检查可缓解序列化负载被篡改的风险。完整的威胁模型与部署配置,请参见 /integrations/laravel/security-and-operations/.
合规性
标题为“合规性”的章节| 主张 | 来源 | 条款 | 参考 ID |
|---|---|---|---|
| 容器解析/生命周期语义 | PSR-11 容器 | §1.1.2 | |
| PSR-4 自动加载前缀映射 | PSR-4 自动加载器 | §3 |
商业背景
标题为“商业背景”的章节安装 nextpdf/premium 后,同一个提供者会公开更多功能:数字签名(PAdES B-B)、PDF/A 归档,以及 e-invoice 契约绑定。此提供者通过完全相同的容器键公开这些功能,因此本页说明的 Core 包无需任何代码变更即可使用这些功能。详情请参见
https://nextpdf.dev/get-license/?intent=laravel-signing。
另请参阅
标题为“另请参阅”的章节- /integrations/laravel/install/ — 安装步骤与可选扩展
- /integrations/laravel/quickstart/ — 可直接运行的 controller 示例
- /integrations/laravel/configuration/ — 每个 config 键均对照验证
config/nextpdf.php - /integrations/laravel/production-usage/ — 以 DI 组装的 controller、错误处理、队列
- /integrations/laravel/boot-and-discovery/ — 自动发现与绑定生命周期
- /integrations/laravel/security-and-operations/ — 威胁模型与部署配置