Symfony API 參考
Symfony 套件提供 bundle(套件)註冊、組態樹、可注入的工廠(用來建立全新文件)、HTTP 回應輔助方法,以及非同步產生用的 Messenger 型別。幾乎所有應用程式程式碼只會用到兩個符號:你注入的 PdfFactory 服務(用來建構 Document),以及把該文件轉成安全 HTTP 回應的 PdfResponse 輔助方法。其餘符號(bundle、extension、compiler pass、組態樹、Messenger DTO 與處理常式)都屬於 wiring(接線設定),只需要設定一次,或交由 Framework(框架)自動管理。
從這裡開始: 如果你剛開始使用,請注入 NextPDF\Symfony\Service\PdfFactory,呼叫 create() 取得全新的 Document,再用 NextPDF\Symfony\Http\PdfResponse::download() 將它回傳。下方第一個範例示範的正是這個流程。
常見任務
標題為「常見任務」的區段以下三個可直接執行的程式碼片段,對應最常見的工作。每一段都只使用後續表格列出且已驗證的符號。
從 controller(控制器)回傳 PDF 下載回應:注入工廠、建構文件,再交給回應輔助方法。
<?php
declare(strict_types=1);
namespace App\Controller;
use NextPDF\Symfony\Http\PdfResponse;use NextPDF\Symfony\Service\PdfFactory;use Symfony\Component\HttpFoundation\Response;use Symfony\Component\Routing\Attribute\Route;
final class InvoiceController{ #[Route('/invoice/{number}', name: 'invoice_pdf')] public function download(PdfFactory $pdf, string $number): Response { $doc = $pdf->create(); $doc->addPage(); $doc->setFont('dejavusans', '', 12); $doc->cell(0, 10, "Invoice #{$number}");
return PdfResponse::download($doc, "invoice-{$number}.pdf"); }}這段程式的作用:PdfFactory::create() 會回傳一份全新、已預先設定好的 Document。PdfResponse::download() 會以 Content-Type: application/pdf、附件處置方式,以及套件固定套用的安全標頭將它送出。
串流傳送大型 PDF 以降低尖峰記憶體用量:改用串流輔助方法,回傳 StreamedResponse。
<?php
declare(strict_types=1);
namespace App\Controller;
use NextPDF\Symfony\Http\PdfResponse;use NextPDF\Symfony\Service\PdfFactory;use Symfony\Component\HttpFoundation\StreamedResponse;use Symfony\Component\Routing\Attribute\Route;
final class ReportController{ #[Route('/report', name: 'report_pdf')] public function report(PdfFactory $pdf): StreamedResponse { $doc = $pdf->create(); $doc->addPage(); $doc->setFont('dejavusans', '', 12); $doc->cell(0, 10, 'Annual report');
return PdfResponse::streamDownload($doc, 'annual-report.pdf'); }}這段程式的作用:PdfResponse::streamDownload() 會分段送出已產生的 PDF,並省略 Content-Length;若要以 inline 方式內嵌顯示,則改用 streamInline()。
派送 PDF 進行非同步產生:將 GeneratePdfMessage 送往 Messenger transport(傳輸),讓繪製工作在 worker 上執行。
<?php
declare(strict_types=1);
namespace App\Controller;
use App\Pdf\InvoicePdfBuilder;use NextPDF\Symfony\Message\GeneratePdfMessage;use Symfony\Component\HttpFoundation\Response;use Symfony\Component\Messenger\MessageBusInterface;use Symfony\Component\Routing\Attribute\Route;
final class QueueController{ #[Route('/invoice/{id}/queue', name: 'invoice_queue')] public function queue(MessageBusInterface $bus, int $id): Response { $bus->dispatch(new GeneratePdfMessage( builderClass: InvoicePdfBuilder::class, outputPath: '/var/storage/invoices/' . $id . '.pdf', builderContext: ['invoice_id' => $id], ));
return new Response('PDF generation queued.', 202); }}這段程式的作用:這個 DTO 帶有一個 builder class-string 以及一個已驗證的輸出路徑。處理常式會 resolve(解析)builder、建構文件,並在 worker 上將它儲存。builder 類別會實作 PdfBuilderInterface,並註冊於 service locator(請參閱 Symfony 快速入門,了解 locator 與 worker 的 wiring)。
需要確認這個可注入服務(用於產生全新文件)的確切建構式與 create() 契約時,請查閱這張表。
| 符號 | 參數 | 預設行為 | 回傳 | 擲出或失敗於 | 備註 |
|---|---|---|---|---|---|
new PdfFactory(DocumentFactoryInterface $factory, array $defaults, ?string $pdfa, array $artisanConfig) | factory:核心工廠;defaults:建立者、作者、語言、邊界;pdfa:選用的 PDF/A 設定檔;artisanConfig:選用的 Chrome renderer(渲染器)設定。 | 只有已設定的預設值才會套用。 | PdfFactory | 容器接線錯誤。 | 此服務可作為單例使用,因為 create() 每次都會回傳一份全新文件。 |
PdfFactory::create() | 無。 | 會套用建立者與語言;只有作者非空白時才套用作者;只有在可用時才套用 PDF/A 與 Artisan 設定。 | NextPDF\Core\Document | 核心組態錯誤。 | 每個請求、命令或訊息各呼叫一次。 |
PdfFactory::setArtisanAvailable(bool $available) | available:編譯期可用性旗標。 | 在 compiler pass 啟用前維持停用。 | void | 預期無。 | 內部掛鉤,由選用的 extension compiler pass 呼叫。 |
PdfFactory::setProAvailable(bool $available) | available:編譯期可用性旗標。 | 在 compiler pass 啟用前維持停用。 | void | 預期無。 | 用來標記 Premium 可用性的內部掛鉤。 |
Bundle、extension 與組態
標題為「Bundle、extension 與組態」的區段這張表涵蓋 wiring 層:註冊 bundle、解析 nextpdf 組態樹,或追蹤選用 extension 偵測時,請查閱它。第二張表則列出組態鍵本身。
| 符號 | 參數 | 預設行為 | 回傳 | 擲出或失敗於 | 備註 |
|---|---|---|---|---|---|
NextPdfBundle::build(ContainerBuilder $container) | Symfony 容器建構器。 | 呼叫父類別的 build 方法,並註冊 OptionalExtensionPass。 | void | Compiler pass 註冊錯誤。 | 啟用選用的 Artisan 與 Premium 功能偵測。 |
NextPdfBundle::getPath() | 無。 | 回傳套件的根路徑。 | string | 預期無。 | 由 Symfony 的 bundle 探索與資源載入使用。 |
NextPdfExtension::load(array $configs, ContainerBuilder $container) | 使用者組態陣列與容器建構器。 | 處理 nextpdf 組態、儲存解析後的參數、載入服務定義,接著檢查必要的 extension。 | void | 組態驗證錯誤、服務載入錯誤,或缺少 extension。 | 必要的 extension 為 mbstring 與 zlib。 |
NextPdfExtension::getAlias() | 無。 | 使用 nextpdf 作為根組態鍵。 | string | 預期無。 | 在 nextpdf: 底下設定此套件。 |
Configuration::getConfigTreeBuilder() | 無。 | 定義已驗證的 nextpdf 組態樹。 | TreeBuilder | Symfony 組態定義錯誤。 | 盡可能與 Laravel 的組態形狀保持一致。 |
OptionalExtensionPass::process(ContainerBuilder $container) | Symfony 容器建構器。 | 偵測選用的 Artisan 與 Premium 服務,並切換工廠的可用性旗標。 | void | Compiler pass 接線錯誤。 | 在容器編譯期間執行。 |
| 組態鍵 | 型別 | 預設行為 | 備註 |
|---|---|---|---|
page_format | 列舉(enum) | A4;允許的值包含 A3、A5、Letter、Legal 與 Tabloid。 | 套用在預設文件建立流程。 |
orientation | 列舉(enum) | P;允許的值為 P 與 L。 | 當某頁需要不同方向時,請改用明確的文件方法呼叫。 |
unit | 列舉(enum) | mm;允許的值為 pt、mm、cm 與 in。 | 讓框架預設值與核心單位保持一致。 |
pdfa | `string | null` | null;允許的值為 4、4e 與 4f。 |
fonts_path / cache_path | string | 專案字型路徑與 kernel 快取路徑。 | 請依執行期角色,確保這兩個路徑維持可讀或可寫。 |
signature.* | array | 預設停用,簽章等級為 B-B。 | 提供憑證、金鑰、密碼、額外憑證與等級。 |
tsa.* | array | 當 URL 為 null 時停用;逾時預設為 30 秒。 | 支援憑證資訊、mTLS 檔案、公開金鑰釘選與 HTTP 政策。 |
ocsp_cache.* | array | 啟用,TTL 為 86400 秒。 | 在可用時供驗證與長期簽章流程使用。 |
messenger.* | array | Transport(傳輸)為 async,逾時 120,重試 3 次。 | 由非同步產生工作流程使用。 |
artisan.* | array | 除非已設定並安裝,否則 Chrome renderer 會維持停用。 | 在選用的 renderer 可用時對映到 ChromeRendererConfig。 |
defaults.* | array | 建立者 NextPDF、作者為空白、語言 en、預設邊界與字型。 | 由 PdfFactory::create() 套用。 |
HTTP 回應
標題為「HTTP 回應」的區段用這張表挑選正確的回應輔助方法:inline 內嵌顯示或下載、緩衝或串流,並檢視每個方法的檔名與標頭行為。
| 符號 | 參數 | 預設行為 | 回傳 | 擲出或失敗於 | 備註 |
|---|---|---|---|---|---|
PdfResponse::inline(Document $document, string $filename = 'document.pdf') | document:已建構的文件;filename:回應檔名。 | 檔名缺少副檔名時會加上 .pdf。 | Symfony\Component\HttpFoundation\Response | 核心序列化錯誤。 | 設定 PDF 內容型別與防禦性標頭。 |
PdfResponse::download(Document $document, string $filename = 'document.pdf') | 與 inline 相同;處置方式為附件。 | 回傳瀏覽器下載回應。 | Response | 與 inline 相同。 | 用於明確的下載。 |
PdfResponse::streamInline(Document $document, string $filename = 'document.pdf') | 與 inline 相同。 | 分段送出已產生的 PDF 位元組。 | StreamedResponse | 與 inline 相同。 | 不會避免文件完整產生。 |
PdfResponse::streamDownload(Document $document, string $filename = 'document.pdf') | 與 streamInline 相同;處置方式為附件。 | 回傳下載串流回應。 | StreamedResponse | 與 streamInline 相同。 | 請在繪製前先套用輸出大小政策。 |
Messenger(訊息傳遞)
標題為「Messenger(訊息傳遞)」的區段建構非同步路徑時,請查閱這張表:它包含你派送的訊息 DTO、你實作的 builder 介面,以及在 worker 上執行的處理常式。
| 符號 | 參數 | 預設行為 | 回傳 | 擲出或失敗於 | 備註 |
|---|---|---|---|---|---|
new GeneratePdfMessage(string $builderClass, string $outputPath, array $builderContext = []) | builderClass:實作 PdfBuilderInterface 的 class-string;outputPath:目標 .pdf;builderContext:可序列化的資料。 | 空 context 陣列。 | 訊息 DTO。 | InvalidArgumentException:當 FQCN 無效、包含串流包裝器、包含 null 位元組、包含路徑穿越、路徑為空,或目標不是 .pdf 時擲出。 | Messenger transport 攜帶的是資料,而非閉包。 |
PdfBuilderInterface::build(Document $document, array $context): Document | document:全新且已設定的文件;context:可序列化的訊息資料。 | 除訊息值本身外,沒有預設 context。 | 已設定的 Document。 | builder 專屬的例外。 | 請讓 builder 保持決定性與冪等性。 |
new GeneratePdfHandler(PdfFactory $pdfFactory, ContainerInterface $builderLocator) | PDF 工廠與已標記的 builder service locator。 | 建構期間不會建立任何文件。 | GeneratePdfHandler | 容器接線錯誤。 | 這個 locator 應只公開 PdfBuilderInterface 的實作。 |
GeneratePdfHandler::__invoke(GeneratePdfMessage $message) | message:已驗證的訊息 DTO。 | 從容器解析 builder、建構文件,並將它儲存。 | void | 缺少 builder 服務、builder 結果無效、核心寫入錯誤。 | 請優先使用服務型 builder,而非靜態回呼。 |
開發注意事項
標題為「開發注意事項」的區段- 請勿把
Document存成服務。請改存PdfFactory,並針對每個工作單元呼叫create()。 - 只將可序列化的 context 排入佇列。請勿將開啟中的串流、閉包或請求物件放入
builderContext。 - 部署具有租戶專屬儲存根目錄的環境時,請讓輸出路徑政策比 DTO 更嚴格。