跳到內容

NextPDF Laravel 啟動與自動探索

Laravel 會透過套件的 composer.json 自動探索 NextPdfServiceProvider。這個 provider 會註冊延遲(deferred)容器繫結,並在 console(主控台)情境下發布組態檔。本頁逐一說明探索機制與各個繫結的生命週期。

Terminal window
composer require nextpdf/laravel
php artisan vendor:publish --tag=nextpdf-config

套件會在自身 composer.jsonextra.laravel 區塊中宣告 provider 與 facade 別名:

resource: composer.json (extra.laravel)
{
"extra": {
"laravel": {
"providers": [
"NextPDF\\Laravel\\NextPdfServiceProvider"
],
"aliases": {
"Pdf": "NextPDF\\Laravel\\Facades\\Pdf"
}
}
}
}

當你執行 composer require 時,Laravel 會讀取這個區塊,並註冊 provider 與別名。你不需要手動編輯 config/app.phpbootstrap/providers.phpextra.laravel.providers 陣列會自動註冊服務 provider,extra.laravel.aliases 則會自動註冊 facade 別名(Laravel 12 套件開發指南, https://laravel.com/docs/12.x/packages,取得日期 2026-05-18)。

NextPdfServiceProvider 同時實作 DeferrableProvider,並遵循標準的 register() / boot() 生命週期。

  1. register() 會將套件組態合併到 nextpdf 鍵下。接著繫結容器項目:字型登錄、影像登錄、文件工廠、PSR-18 HTTP 用戶端、timestamp 用戶端、簽章器、文件,以及 e-invoice 合約。每個繫結都是閉包,因此此階段不會建構任何重量級物件。
  2. boot() 會檢查 mbstringzlib 這兩個 PHP 擴充是否已載入。它只會在 nextpdf-config 標籤下註冊可發布的組態,且僅在 runningInConsole() 為 true 時。

這個 provider 採延遲載入,因此只有在你 resolve(解析)provides() 所回傳的其中一個項目時,register() 才會執行。解析其他無關的容器鍵並不會啟動 NextPDF。

PSR-11 允許使用相同識別碼連續呼叫兩次 get(),並依繫結策略回傳不同的值(PSR-11 §1.1.2)。這個 provider 刻意倚賴這項特性:

繫結鍵生命週期備註
FontRegistryInterface(含 FontRegistry 別名)單例(singleton),暖機後鎖定preload_fonts 進行暖機;鎖定後,任何請求都無法變更它
ImageRegistry單例(singleton)有界 LRU 快取,大小由 image_cache_mb 決定;不鎖定
DocumentFactoryInterface(含 DocumentFactory 別名)單例(singleton)無狀態;共用前述兩個登錄
Psr\Http\Client\ClientInterface單例(singleton)具備請求偽造防護的用戶端,包覆一個 curl 用戶端;建構來源為 tsa.*
TsaClient受限範圍(scoped)null(當 tsa.url 為空時)
SignerInterface工廠(factory)null(當簽章停用或憑證為空時)
PdfDocumentInterface(含 nextpdf 別名)工廠(factory)每次解析都會產生全新的 NextPDF\Core\Document,並套用預設中繼資料
EmbedderInterfaceValidatorInterfaceProfileInterfaceSchematronRunnerInterface工廠(factory)解析為 Premium 具體實作;首次解析時,若缺少此套件就會發生錯誤:nextpdf/premium

文件繫結會將 defaults.creatordefaults.language,以及(非空時)defaults.author 套用到每份新建立的文件。當 pdfa 不為 null 時,會啟用 PDF/A(Premium)。當存在 artisan 區段且有 Chrome 瀏覽器工廠類別時,會套用 Chrome renderer(渲染器)組態。

容器上的 has() 接受單一字串識別碼(PSR-11 §1.1.2)。e-invoice 合約已被繫結,因此即使缺少 Premium,對它們呼叫 has() 仍會回傳 true。缺少的具體實作只會在建構時出錯。

將套件加入應用程式的 dont-discover 陣列,再手動註冊 provider:

resource: application composer.json
{
"extra": {
"laravel": {
"dont-discover": ["nextpdf/laravel"]
}
}
}
resource: bootstrap/providers.php
<?php
declare(strict_types=1);
return [
App\Providers\AppServiceProvider::class,
NextPDF\Laravel\NextPdfServiceProvider::class,
];

每個鍵都依此順序解析:環境變數 → 已發布的 config/nextpdf.php 值 → 在 register() 中合併的套件預設值。大多數鍵都接受 NEXTPDF_* 名稱或舊版 TCPDF_* 環境變數名稱。建議優先使用 NEXTPDF_*

Terminal window
php artisan package:discover --ansi

若輸出中出現列出 nextpdf/laravel 的那一行,就表示探索成功。由於 provider 是延遲載入,繫結本身要到第一次解析後才會出現。這行探索訊息才是正確的成功訊號。

  • 組態發布只會在 console 情境下註冊,因此純 Web 請求永遠不會觸發它。請從 CLI 執行 vendor:publish
  • 除了登錄、工廠、HTTP 用戶端、簽章器、timestamp 與文件等鍵,provides() 還包含四個 e-invoice 合約鍵。
  • 全新安裝在第一次相關解析之前,可能看起來像沒有作用。這是延遲 provider 的設計,並非錯誤。

register() 是 O(1)——只有閉包。字型登錄暖機的複雜度為預載字型數的 O(f),且每個 worker 行程只執行一次。延遲載入 provider 可讓 NextPDF 的建構成本不落在 Framework(框架)啟動路徑上,直到實際用到某個繫結為止。

延遲設計縮小了啟動時的攻擊面。鎖定的字型登錄可防止長生命週期 worker 發生跨請求的字型狀態變更。如需完整的威脅涵蓋說明,請見 /integrations/laravel/security-and-operations/。

主張來源條款參考 ID(reference_id)
連續解析可能因繫結策略而有所不同PSR-11 容器(Container)§1.1.2
has() 接受單一字串識別碼PSR-11 容器(Container)§1.1.2

Laravel 探索鍵名已對照官方 Laravel 12 套件文件查證(https://laravel.com/docs/12.x/packages,取得日期 2026-05-18)。

Premium 具體實作會透過相同的延遲繫結鍵解析。這是選用的 Enterprise 能力,而本頁所述的 Core 套件不需修改任何程式碼即可採用此能力。請見 https://nextpdf.dev/get-license/?intent=laravel-signing

  • /integrations/laravel/install/ — 安裝與發布
  • /integrations/laravel/overview/ — 套件架構
  • /integrations/laravel/integration/ — 端對端接線教學
  • /integrations/laravel/configuration/ — 所有組態鍵