Lewati ke konten

Panduan cepat NextPDF Symfony

Injeksikan PdfFactory, buat sebuah Document, lalu kembalikan melalui PdfResponse. Saat Anda memerlukan pembuatan di latar belakang, kirim GeneratePdfMessage ke transport Messenger.

Injeksikan NextPDF\Symfony\Service\PdfFactory. Metode create()-nya mengembalikan NextPDF\Core\Document baru. Metode ini menerapkan nilai standar yang Anda konfigurasikan untuk creator, author, dan bahasa. Kembalikan dokumen melalui NextPDF\Symfony\Http\PdfResponse.

src/Controller/InvoiceController.php
<?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->cell(0, 10, "Invoice #{$number}", newLine: true);
$doc->cell(0, 10, 'Thank you for your business.');
return PdfResponse::download($doc, "invoice-{$number}.pdf");
}
}

PdfResponse::download() mengembalikan Symfony\Component\HttpFoundation\Response. Metode ini menyetel Content-Type: application/pdf, disposisi attachment, Content-Length, dan header keamanan tetap dari bundle. Symfony mendokumentasikan kelas Response standar beserta model header-nya (https://symfony.com/doc/current/components/http_foundation.html).

Gunakan inline() saat Anda ingin browser menampilkan PDF, bukan mengunduhnya:

return PdfResponse::inline($doc, 'preview.pdf');

Disposisinya berubah menjadi inline. Semua header lainnya tetap sama.

Gunakan varian streaming untuk dokumen berukuran besar. Varian ini mengirimkan PDF dalam potongan 64 KB, sehingga mengurangi puncak penggunaan memori. Varian ini mengembalikan Symfony\Component\HttpFoundation\StreamedResponse dan menghilangkan Content-Length.

return PdfResponse::streamDownload($doc, 'annual-report.pdf');

Gunakan streamInline() untuk streaming secara inline. Symfony mendokumentasikan kontrak callback StreamedResponse, yaitu callable void yang mengosongkan output (https://symfony.com/doc/current/components/http_foundation.html).

Saat symfony/messenger terpasang, Anda dapat memindahkan proses pembuatan dari thread permintaan.

Implementasikan NextPDF\Symfony\Message\PdfBuilderInterface. Handler memberi Anda Document baru yang sudah dikonfigurasi, beserta konteks dari pesan yang dapat diserialisasi.

src/Pdf/InvoicePdfBuilder.php
<?php
declare(strict_types=1);
namespace App\Pdf;
use NextPDF\Core\Document;
use NextPDF\Symfony\Message\PdfBuilderInterface;
final class InvoicePdfBuilder implements PdfBuilderInterface
{
public function build(Document $document, array $context): Document
{
$document->addPage();
$document->setFont('dejavusans', '', 12);
$document->cell(0, 10, 'Invoice #' . $context['invoice_id']);
return $document;
}
}

Handler mengambil builder dari service locator PHP Standard Recommendation 11 (PSR-11) yang dipetakan berdasarkan nama kelas. Hanya builder yang terdaftar yang dapat diakses. Tambahkan builder ke sebuah locator di config/services.yaml:

services:
App\Pdf\InvoicePdfBuilder: ~
nextpdf.pdf_builder_locator:
class: Symfony\Component\DependencyInjection\ServiceLocator
arguments:
- 'App\Pdf\InvoicePdfBuilder': '@App\Pdf\InvoicePdfBuilder'
tags: ['container.service_locator']
NextPDF\Symfony\Message\GeneratePdfHandler:
arguments:
$builderLocator: '@nextpdf.pdf_builder_locator'

Handler meminta builder kepada locator berdasarkan id class-string-nya. Dalam PSR-11, pengenal container adalah string yang mengidentifikasi sebuah entri secara unik (PSR-11 §1.1.2).

Injeksikan Symfony\Component\Messenger\MessageBusInterface, lalu kirim pesan:

src/Controller/ReportController.php
<?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 ReportController
{
#[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);
}
}

GeneratePdfMessage adalah data transfer object (DTO) yang bersifat readonly. Konstruktornya menolak jalur output yang kosong, tidak diakhiri dengan .pdf, berisi segmen path-traversal, menggunakan skema stream-wrapper, atau mengandung byte null. Konstruktor juga mewajibkan builderClass berupa nama kelas yang valid secara sintaksis. Handler memvalidasi ulang jalur output saat eksekusi, sebelum menulis. Jika suatu jalur aman saat dispatch tetapi tidak aman saat dikonsumsi, handler tetap menolaknya. Atribut #[AsMessageHandler] dan kontrak dispatch MessageBusInterface mengikuti model standar Symfony Messenger (https://symfony.com/doc/current/messenger.html).

Di config/packages/messenger.yaml, rutekan pesan ke sebuah transport:

framework:
messenger:
transports:
async: '%env(MESSENGER_TRANSPORT_DSN)%'
routing:
NextPDF\Symfony\Message\GeneratePdfMessage: async

Kemudian jalankan worker:

Terminal window
php bin/console messenger:consume async
Terminal window
php bin/console debug:container --tag=container.service_locator
php bin/console messenger:consume async --limit=1 -vv

Perintah pertama mengonfirmasi bahwa builder locator telah terdaftar. Perintah kedua mengonsumsi satu pesan di antrean dan mencetak progres handler.

  • /integrations/symfony/configuration/ — sesuaikan nilai standar, fon, dan layanan dokumen.
  • /integrations/symfony/production-usage/ — tinjau keamanan worker dan streaming saat beban tinggi.
  • /integrations/symfony/troubleshooting/ — atasi masalah boot dan runtime yang umum.

Setiap baris merupakan klaim normatif yang dibuat pada halaman ini dan dikaitkan ke reference_id 64-hex lengkap dari korpus standards development organization (SDO) yang terbatas. _sidecars/rag-citations.yaml memuat provenans, termasuk manifes korpus dan transport pengambilan.

SpesifikasiKlausulreference_idKlaim
PSR-11psr_11_container#1.1.2.p4Kontrak pengenal has()/get() container
  • /integrations/symfony/overview/ — tinjau ringkasan kapabilitas.
  • /integrations/symfony/install/ — pasang dan daftarkan bundle.
  • /integrations/symfony/integration/ — tinjau referensi wiring menyeluruh.