تخطَّ إلى المحتوى

دليل بدء سريع لـ NextPDF مع Symfony

احقن PdfFactory، وأنشئ Document، ثم أعِده عبر PdfResponse. عندما تحتاج إلى التوليد في الخلفية، أرسِل GeneratePdfMessage إلى ناقل ⁨Messenger⁩.

الخطوة 1 — إنشاء مستند ⁨PDF⁩ في وحدة تحكم

قسم بعنوان «الخطوة 1 — إنشاء مستند ⁨PDF⁩ في وحدة تحكم»

احقن NextPDF\Symfony\Service\PdfFactory. تُرجِع طريقة create() الخاصة به مثيلًا جديدًا من NextPDF\Core\Document. وتطبّق القيم الافتراضية المُهيَّأة لديك للمُنشئ والمؤلف واللغة. أعِد المستند عبر 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() كائن Symfony\Component\HttpFoundation\Response. وتضبط Content-Type: application/pdf، وترتيب العرض من نوع attachment، وContent-Length، إضافةً إلى رؤوس الأمان الثابتة في الحزمة. توثّق ⁨Symfony⁩ الفئة القياسية Response ونمط رؤوسها (https://symfony.com/doc/current/components/http_foundation.html).

الخطوة 2 — عرض مستند ⁨PDF⁩ ضمن الصفحة

قسم بعنوان «الخطوة 2 — عرض مستند ⁨PDF⁩ ضمن الصفحة»

استخدم inline() عندما تريد من المتصفح عرض ملف ⁨PDF⁩ بدلًا من تنزيله:

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

يتغيّر ترتيب العرض إلى inline. وتبقى جميع الرؤوس الأخرى كما هي.

الخطوة 3 — بثّ مستند ⁨PDF⁩ كبير

قسم بعنوان «الخطوة 3 — بثّ مستند ⁨PDF⁩ كبير»

استخدم النُّسخ المبثوثة للمستندات الكبيرة. فهي تُصدِر ملف ⁨PDF⁩ في كُتل بحجم 64 ⁨KB⁩، مما يقلّل ذروة استهلاك الذاكرة. وتُرجِع Symfony\Component\HttpFoundation\StreamedResponse وتحذف Content-Length.

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

استخدم streamInline() للبثّ ضمن الصفحة. توثّق ⁨Symfony⁩ عقد ردّ النداء الخاص بـ StreamedResponse، وهو دالة قابلة للاستدعاء من نوع void تفرغ المُخرَجات (https://symfony.com/doc/current/components/http_foundation.html).

الخطوة 4 — إنشاء مستند ⁨PDF⁩ بشكل غير متزامن

قسم بعنوان «الخطوة 4 — إنشاء مستند ⁨PDF⁩ بشكل غير متزامن»

عند تثبيت symfony/messenger، يمكنك نقل التوليد إلى خارج خيط الطلب.

نفِّذ NextPDF\Symfony\Message\PdfBuilderInterface. يمنحك المُعالِج مثيلًا جديدًا مُهيَّأ مسبقًا من Document والسياق القابل للتسلسل من الرسالة.

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;
}
}

4⁨b⁩ — تسجيل الباني في المُحدِّد

قسم بعنوان «4⁨b⁩ — تسجيل الباني في المُحدِّد»

يحلّ المُعالِج البُناة من مُحدِّد خدمات ⁨PHP Standard Recommendation 11⁩ (⁨PSR-11⁩) مُفهرَس باسم الفئة. لا يمكن الوصول إلا إلى البُناة المُسجَّلين. أضِف الباني إلى مُحدِّد في 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'

يطلب المُعالِج من المُحدِّد الباني عبر مُعرِّفه النصي المطابق للفئة. في ⁨PSR-11⁩، مُعرِّف الحاوية سلسلة نصية تُعرِّف مُدخَلًا بشكل فريد (⁨PSR-11⁩ §1.1.2).

احقن Symfony\Component\Messenger\MessageBusInterface، ثم أرسِل الرسالة:

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 هو كائن نقل بيانات (⁨DTO⁩) من نوع readonly. يرفض مُنشئه مسارات الإخراج الفارغة، أو التي لا تنتهي بـ .pdf، أو التي تتضمّن مقاطع اجتياز مسار، أو تستخدم مخططات مُغلِّفات الدفق، أو تحتوي على بايتات خالية. كما يشترط أن يكون builderClass اسم فئة صحيحًا نحويًا. يتحقق المُعالِج من مسار الإخراج مرة أخرى وقت التنفيذ، قبل الكتابة. إذا كان المسار آمنًا عند الإرسال لكنه غير آمن وقت الاستهلاك، فإن المُعالِج يرفضه رغم ذلك. تتبع السمة #[AsMessageHandler] وعقد الإرسال الخاص بـ MessageBusInterface نموذج ⁨Symfony Messenger⁩ القياسي (https://symfony.com/doc/current/messenger.html).

4⁨d⁩ — توجيه الرسالة وتشغيل عامل

قسم بعنوان «4⁨d⁩ — توجيه الرسالة وتشغيل عامل»

في config/packages/messenger.yaml، وجِّه الرسالة إلى ناقل:

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

ثم شغِّل عاملًا:

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

يؤكد الأمر الأول أن مُحدِّد البُناة مُسجَّل. ويستهلك الأمر الثاني رسالة واحدة من قائمة الانتظار ويطبع تقدّم المُعالِج.

  • /⁨integrations/symfony/configuration/⁩ — اضبط القيم الافتراضية والخطوط وخدمة المستند.
  • /⁨integrations/symfony/production-usage/⁩ — راجِع أمان العامل والبثّ تحت الحِمل.
  • /⁨integrations/symfony/troubleshooting/⁩ — حُلّ مشكلات بدء التشغيل ووقت التشغيل الشائعة.

كل صف هو ادعاء معياري وارد في هذه الصفحة ومثبَّت إلى reference_id سداسي عشري كامل من 64 خانة من مجموعة منظمة تطوير المعايير (⁨SDO⁩) المُقيَّدة. يحتوي _sidecars/rag-citations.yaml على بيانات المنشأ، بما في ذلك بيان المجموعة وناقل الاسترجاع.

المواصفةالبند⁨reference_id⁩الادعاء
⁨PSR-11⁩psr_11_container#1.1.2.p4عقد المُعرِّف في ⁨has⁩()/⁨get⁩() للحاوية
  • /⁨integrations/symfony/overview/⁩ — راجِع ملخّص الإمكانات.
  • /⁨integrations/symfony/install/⁩ — ثبِّت الحزمة وسجِّلها.
  • /⁨integrations/symfony/integration/⁩ — راجِع مرجع التوصيل الشامل من البداية إلى النهاية.