การใช้งานจริงใน CodeIgniter 4
ภาพรวมโดยย่อ
หัวข้อที่มีชื่อว่า “ภาพรวมโดยย่อ”คอนโทรลเลอร์สำหรับระบบจริงจะรับเซอร์วิส NextPDF เป็นอ็อบเจ็กต์รูปธรรม จัดการลำดับชั้นของ exception ที่บันทึกไว้อย่างชัดเจน ส่งสัญญาณเพื่อการสังเกตการณ์ และย้ายงาน Portable Document Format (PDF) ที่ใช้เวลานานออกจากคำขอผ่านคิวของ CodeIgniter 4
ภาพรวมเชิงแนวคิด
หัวข้อที่มีชื่อว่า “ภาพรวมเชิงแนวคิด”CodeIgniter 4 จะจัดเตรียมการอ้างอิงของเซอร์วิสในแพ็กเกจผ่านโลเคเตอร์ของตัวเอง ในรูปแบบ service-locator อ็อบเจ็กต์จะได้รับคอนเทนเนอร์ แล้วใช้คอนเทนเนอร์นั้นดึงการอ้างอิงของตัวเอง แนวทางของ PHP Standard Recommendation (PSR) ไม่สนับสนุนรูปแบบดังกล่าว (PSR-11 §1.3, modal SHOULD NOT) เพื่อให้เป็นไปตามแนวทางดังกล่าว ให้จัดเตรียมการอ้างอิงของเซอร์วิส NextPDF แต่ละรายการเพียงครั้งเดียวที่ขอบเขตของคอนโทรลเลอร์ แล้วจึงส่งอ็อบเจ็กต์รูปธรรมเข้าไปยังชั้นด้านใน อย่าส่งคลาส Services หรือคอนเทนเนอร์เข้าไปในโค้ดโดเมนของคุณ
ตัวอย่าง PHP ทุกรายการวาง declare(strict_types=1); ไว้บนบรรทัดของตัวเอง (PSR-12 §x1.x3.p34)
พื้นผิว API
หัวข้อที่มีชื่อว่า “พื้นผิว API”| ประเด็นสำหรับระบบจริง | พื้นผิวที่ได้รับการตรวจสอบแล้ว |
|---|---|
| จัดเตรียมการอ้างอิงของเซอร์วิส | Services::pdf(false), Services::pdfDocument(false), Services::documentFactory() |
| สร้างการตอบสนอง | PdfResponse::download() / inline() → DownloadResponse |
| ดักจับความล้มเหลว | NextPDF\Exception\NextPdfException (ชนิดฐานของอีโคซิสเต็ม) |
| การสร้างแบบอะซิงโครนัส | GeneratePdfJob ที่ลงทะเบียนไว้ใน Config\Queue::$jobHandlers |
| การป้องกันเส้นทาง / callable | GeneratePdfJob โยน InvalidArgumentException |
คอนโทรลเลอร์บนระบบจริง — การจัดการข้อผิดพลาดและความสามารถในการสังเกตการณ์
หัวข้อที่มีชื่อว่า “คอนโทรลเลอร์บนระบบจริง — การจัดการข้อผิดพลาดและความสามารถในการสังเกตการณ์”เอนจินหลักจะโยน exception ที่สืบทอดจาก NextPDF\Exception\NextPdfException ทั้งหมด ให้ดักจับชนิดเดียวนี้เพื่อครอบคลุมความล้มเหลวของทั้งแกนหลักและส่วนขยาย บล็อก catch นี้จะบันทึกบริบทและส่งคืนการตอบสนองข้อผิดพลาดที่กำหนดไว้ ไม่ใช่ catch แบบว่างเปล่า
<?php
declare(strict_types=1);
namespace App\Controllers;
use CodeIgniter\HTTP\DownloadResponse;use CodeIgniter\HTTP\ResponseInterface;use NextPDF\CodeIgniter\Config\Services;use NextPDF\Exception\NextPdfException;use Psr\Log\LoggerInterface;
final class InvoiceController extends BaseController{ public function download(int $id): DownloadResponse|ResponseInterface { /** @var LoggerInterface $logger */ $logger = \service('logger');
$start = \hrtime(true);
try { $pdf = Services::pdf(false); $pdf->document()->addPage(); $pdf->document()->cell(0, 10, "Invoice #{$id}");
$response = $pdf->download("invoice-{$id}.pdf");
$logger->info('pdf.invoice.generated', [ 'invoice_id' => $id, 'elapsed_ms' => (\hrtime(true) - $start) / 1_000_000, ]);
return $response; } catch (NextPdfException $e) { $logger->error('pdf.invoice.failed', [ 'invoice_id' => $id, 'exception' => $e::class, 'message' => $e->getMessage(), ]);
return $this->response ->setStatusCode(ResponseInterface::HTTP_INTERNAL_SERVER_ERROR) ->setJSON(['error' => 'pdf_generation_failed', 'invoice_id' => $id]); } }}Services::pdf(false) ส่งคืนไลบรารีใหม่พร้อมเอกสารพื้นฐานใหม่ในทุกการเรียกใช้ คำขอที่ทำงานพร้อมกันจะไม่ใช้สถานะของเอกสารร่วมกันเลย การทดสอบเชิงฟังก์ชันของแพ็กเกจยืนยันพฤติกรรมนี้
อายุการใช้งานเซอร์วิสที่ปลอดภัยสำหรับเวิร์กเกอร์
หัวข้อที่มีชื่อว่า “อายุการใช้งานเซอร์วิสที่ปลอดภัยสำหรับเวิร์กเกอร์”รีจิสทรีของฟอนต์และรูปภาพถูกออกแบบให้เป็นซิงเกิลตันตลอดอายุของโปรเซส รีจิสทรีของฟอนต์จะวอร์มและล็อกเพียงครั้งเดียว รีจิสทรีของรูปภาพเป็นแคชแบบ least recently used (LRU) ที่มีขนาดจำกัด ในเวิร์กเกอร์ที่มีอายุยืนยาว (CodeIgniter spark server, รันเนอร์สไตล์ RoadRunner หรือเวิร์กเกอร์คิว) พฤติกรรมนี้เป็นไปตามเจตนา รีจิสทรีที่มีต้นทุนสูงจะคงอยู่ ส่วนเอกสารทุกฉบับยังคงเป็นเอกสารใหม่ อย่าร้องขอเอกสารที่ใช้ร่วมกัน (Services::pdfDocument(true)) ในโค้ดของคำขอหรือโค้ดของงาน ตัวเลือกนี้มีไว้เพื่อรีเซ็ตในการทดสอบเท่านั้น และจะทำให้เนื้อหาถูกใช้ร่วมกันข้ามคำขอ
การสร้างแบบอะซิงโครนัสด้วยคิวของ CodeIgniter
หัวข้อที่มีชื่อว่า “การสร้างแบบอะซิงโครนัสด้วยคิวของ CodeIgniter”GeneratePdfJob ย้ายการสร้าง PDF ออกจากคำขอผ่าน codeigniter4/queue รันไทม์ของคิวต้องใช้การตั้งค่าสองรายการ กำหนดค่าทั้งสองรายการให้ถูกต้อง
1. ลงทะเบียนตัวจัดการงานด้วยชื่อ
หัวข้อที่มีชื่อว่า “1. ลงทะเบียนตัวจัดการงานด้วยชื่อ”คิวจะจัดเตรียมงานด้วย คีย์ชื่อ ไม่ใช่ด้วยสตริงคลาส ตัวจัดการคิวจะตรวจสอบชื่องานที่ส่งเข้ามาเทียบกับคีย์ของ Config\Queue::$jobHandlers ตัวจัดการคิวจะปฏิเสธชื่อที่ไม่รู้จักด้วย CodeIgniter\Queue\Exceptions\QueueException ลงทะเบียนงานใน app/Config/Queue.php:
<?php
declare(strict_types=1);
namespace Config;
use CodeIgniter\Queue\Config\Queue as BaseQueue;use NextPDF\CodeIgniter\Jobs\GeneratePdfJob;
final class Queue extends BaseQueue{ /** @var array<string, class-string> */ public array $jobHandlers = [ 'generate-pdf' => GeneratePdfJob::class, ];}2. ส่งงานด้วยชื่อที่ลงทะเบียนไว้
หัวข้อที่มีชื่อว่า “2. ส่งงานด้วยชื่อที่ลงทะเบียนไว้”ส่งงานเข้าคิวโดยใช้ชื่อที่ลงทะเบียนไว้เป็นอาร์กิวเมนต์ที่สอง อาร์กิวเมนต์แรกคือชื่อคิว ส่วนอาร์กิวเมนต์ที่สามคืออาร์เรย์ข้อมูลของงาน
<?php
declare(strict_types=1);
namespace App\Controllers;
use CodeIgniter\HTTP\ResponseInterface;
final class InvoiceController extends BaseController{ public function queueInvoice(int $id): ResponseInterface { \service('queue')->push('pdf-queue', 'generate-pdf', [ 'builder' => 'App\\PdfBuilders\\InvoiceBuilder::build', 'outputPath' => WRITEPATH . 'pdfs/invoice-' . $id . '.pdf', 'context' => ['invoice_id' => $id], ]);
return $this->response ->setStatusCode(ResponseInterface::HTTP_ACCEPTED) ->setJSON(['status' => 'queued', 'invoice_id' => $id]); }}3. สร้างบิลเดอร์ภายใต้ App\PdfBuilders
หัวข้อที่มีชื่อว่า “3. สร้างบิลเดอร์ภายใต้ App\PdfBuilders”งานนี้อนุญาตให้ใช้ callable ของบิลเดอร์เฉพาะในเนมสเปซ App\PdfBuilders เท่านั้น และจำกัดเส้นทางเอาต์พุตไว้ที่ WRITEPATH/pdfs/ ให้สร้างบิลเดอร์เป็นเมท็อดแบบสแตติก บิลเดอร์จะได้รับ Document ใหม่และอาร์เรย์บริบท จากนั้นจึงส่งคืนเอกสาร
<?php
declare(strict_types=1);
namespace App\PdfBuilders;
use NextPDF\Core\Document;
final class InvoiceBuilder{ /** @param array<string, mixed> $context */ public static function build(Document $document, array $context): Document { $invoiceId = (int) ($context['invoice_id'] ?? 0);
$document->addPage(); $document->cell(0, 10, "Invoice #{$invoiceId}");
return $document; }}รันเวิร์กเกอร์
หัวข้อที่มีชื่อว่า “รันเวิร์กเกอร์”php spark queue:work pdf-queueการรันงานแต่ละครั้งจะเริ่มต้นด้วยเอกสารใหม่จาก Services::pdfDocument() จากนั้นจึงเรียกใช้บิลเดอร์ แล้วบันทึกไปยังเส้นทางที่ตรวจสอบความถูกต้องแล้ว การทดสอบของแพ็กเกจยืนยันว่าการรันงานสองครั้งที่ต่อเนื่องกันจะไม่ใช้สถานะของเอกสารร่วมกัน
กรณีพิเศษและข้อควรระวัง
หัวข้อที่มีชื่อว่า “กรณีพิเศษและข้อควรระวัง”- คิวจะปฏิเสธ
GeneratePdfJob::classในฐานะชื่องานเมื่อส่งเข้าคิว เพราะไม่ใช่คีย์ที่ลงทะเบียนไว้'generate-pdf'ให้ส่งคีย์jobHandlersเสมอ - สตริงของบิลเดอร์ต้องตรงกับ
App\PdfBuilders\<Class>::<method>ทุกประการ ฟังก์ชัน เนมสเปซอื่น หรือเพย์โหลดที่มีคำนำหน้าหรือคำต่อท้ายจะทำให้เกิดInvalidArgumentExceptionก่อนที่จะมีโค้ดใดทำงาน - เส้นทางเอาต์พุตเมื่อจัดเตรียมแล้วต้องอยู่ภายใน
WRITEPATH/pdfs/และลงท้ายด้วย.pdf(ไม่คำนึงถึงตัวพิมพ์ใหญ่เล็ก) เส้นทางแบบ traversal และเส้นทางที่มีคำนำหน้าระดับเดียวกันจะถูกปฏิเสธ codeigniter4/queueเป็นการอ้างอิงสำหรับการพัฒนาเท่านั้นของแพ็กเกจ ให้ require การอ้างอิงนี้ในแอปพลิเคชันที่รันเวิร์กเกอร์
ประสิทธิภาพ
หัวข้อที่มีชื่อว่า “ประสิทธิภาพ”รีจิสทรีจะถูกสร้างเพียงครั้งเดียวต่อหนึ่งโปรเซสของเวิร์กเกอร์ ต้นทุนการสร้างเอกสารขึ้นอยู่กับเนื้อหา ไม่ใช่อะแดปเตอร์ สำหรับงานแบบกลุ่มขนาดใหญ่ ให้ใช้เส้นทางผ่านคิวเพื่อให้เวิร์กเกอร์ที่รับคำขอยังคงตอบสนองได้ กำหนด performance_budget ในเรซิพีใด ๆ ที่มีเป้าหมายวัดผลได้
หมายเหตุด้านความปลอดภัย
หัวข้อที่มีชื่อว่า “หมายเหตุด้านความปลอดภัย”งานคิวเป็นพื้นผิวที่มีความเสี่ยงสูงที่สุด เมื่อเข้าถึงโบรกเกอร์ได้ ให้ถือว่าเพย์โหลดของคิวอยู่ภายใต้อิทธิพลของผู้โจมตี allowlist ของ callable และการจำกัดเส้นทางอธิบายไว้ใน /integrations/codeigniter/security-and-operations/ พร้อมกับกรณีการปฏิเสธที่ได้รับการตรวจสอบแล้ว
ความสอดคล้อง
หัวข้อที่มีชื่อว่า “ความสอดคล้อง”- คอนโทรลเลอร์จะรับเซอร์วิสที่เป็นอ็อบเจ็กต์รูปธรรม ไม่ใช่คอนเทนเนอร์ ซึ่งสอดคล้องกับแนวทางเกี่ยวกับ service-locator ของ PSR-11 §1.3
บริบทเชิงพาณิชย์
หัวข้อที่มีชื่อว่า “บริบทเชิงพาณิชย์”แกนหลักของ NextPDF อยู่ภายใต้ Apache-2.0 หากต้องการสร้างเอาต์พุตที่มีการลงนามและ PDF/A ในงานคิว ให้ติดตั้ง NextPDF Pro หรือ Enterprise ในสภาพแวดล้อมของเวิร์กเกอร์ แพ็กเกจ CodeIgniter เปิดเผยเมท็อดเซอร์วิสที่เกี่ยวข้อง เมท็อดเหล่านี้ส่งคืน null จนกว่าจะติดตั้งแพ็กเกจ Premium ที่ตรงกัน ดู </get-license/?intent=codeigniter-async-signing>
ดูเพิ่มเติม
หัวข้อที่มีชื่อว่า “ดูเพิ่มเติม”- /integrations/codeigniter/quickstart/ — เวอร์ชันขั้นต่ำของคอนโทรลเลอร์เหล่านี้
- /integrations/codeigniter/configuration/ — การลงนามด้วย Time Stamping Authority (TSA) และการกำหนดค่าเส้นทาง
- /integrations/codeigniter/security-and-operations/ — โมเดลภัยคุกคามของคิวและการเสริมความแข็งแกร่ง
- /integrations/codeigniter/troubleshooting/ — รูปแบบความล้มเหลวของคิวและการค้นพบ
- /integrations/codeigniter/integration/ — ข้อมูลอ้างอิงการเชื่อมต่อและการทดสอบเบื้องต้น