跳轉到

Service Provider

NextPdfServiceProvider 繼承自 Laravel 的 DeferrableProvider,確保 NextPDF 相關容器綁定僅在首次使用時才執行初始化,不影響每次請求的啟動時間。

PHP Compatibility

This example uses PHP 8.5 syntax. If your environment runs PHP 8.1 or 7.4, use NextPDF Backport for a backward-compatible build.

自動探索

Laravel 11+ 透過 Package Discovery 自動載入此 Provider,無需手動註冊。如需停用自動探索,可在 composer.json 中加入:

{
    "extra": {
        "laravel": {
            "dont-discover": [
                "nextpdf/laravel"
            ]
        }
    }
}

如需手動註冊,請在 config/app.phpproviders 陣列中加入:

'providers' => ServiceProvider::defaultProviders()->merge([
    NextPDF\Laravel\NextPdfServiceProvider::class,
])->toArray(),

容器綁定

Provider 在 register() 方法中完成以下綁定:

抽象 具體實作 生命週期
NextPDF\Core\Contracts\ProcessInterface NextPDF\Core\Process singleton
NextPDF\Core\Contracts\DocumentFactoryInterface NextPDF\Core\DocumentFactory singleton
NextPDF\Laravel\Contracts\PdfGeneratorInterface NextPDF\Laravel\PdfGenerator scoped (per-request)
// 透過 DI 容器注入(建議方式)
use NextPDF\Core\Contracts\DocumentFactoryInterface;

final class ReportService
{
    public function __construct(
        private readonly DocumentFactoryInterface $factory,
    ) {}

    public function generate(): string
    {
        $document = $this->factory->create();
        // ...
        return $document->output();
    }
}

設定檔

執行 php artisan vendor:publish --tag=config 後,設定檔發佈至 config/nextpdf.php

<?php

declare(strict_types=1);

return [
    /*
    |--------------------------------------------------------------------------
    | 預設文件設定
    |--------------------------------------------------------------------------
    */
    'document' => [
        'page_size'    => 'A4',
        'orientation'  => 'portrait',
        'margin_mm'    => 15.0,
        'author'       => env('APP_NAME', 'Laravel'),
        'creator'      => 'NextPDF',
    ],

    /*
    |--------------------------------------------------------------------------
    | Spectrum 加速器
    |--------------------------------------------------------------------------
    */
    'spectrum' => [
        'enabled'  => env('NEXTPDF_SPECTRUM_ENABLED', false),
        'binary'   => env('NEXTPDF_SPECTRUM_BINARY', null),
    ],

    /*
    |--------------------------------------------------------------------------
    | Octane 相容性
    |--------------------------------------------------------------------------
    */
    'octane' => [
        'flush_on_request_end' => true,
    ],

    /*
    |--------------------------------------------------------------------------
    | HTTP 回應預設值
    |--------------------------------------------------------------------------
    */
    'response' => [
        'cache_max_age'       => 0,         // 秒;0 = no-cache
        'x_content_type_nosniff' => true,
        'content_security_policy' => "default-src 'none'",
    ],
];

boot() 鉤子

Provider 的 boot() 方法執行以下操作:

  1. 在 Octane 請求結束時呼叫 Process::flush()(若 octane.flush_on_request_end = true
  2. 載入套件路由(若應用程式使用 nextpdf.routes.enable
  3. 發佈 stub 與設定檔

測試環境

在功能測試中,可使用 NextPdfFake 代替真實的 DocumentFactory,避免在測試中實際生成 PDF:

use NextPDF\Laravel\Testing\NextPdfFake;

beforeEach(function () {
    NextPdfFake::swap(); // 將容器中的 DocumentFactory 替換為 Fake
});

it('dispatches pdf generation', function () {
    $this->post('/invoices/1/download');

    NextPdfFake::assertGenerated(fn ($doc) => $doc->getTitle() === 'Invoice #1');
});

參見