Użycie produkcyjne w CodeIgniter 4
W skrócie
Dział zatytułowany „W skrócie”Kontrolery produkcyjne otrzymują konkretne usługi NextPDF. Jawnie obsługują udokumentowaną hierarchię wyjątków i emitują sygnały obserwowalności. Przenieś długotrwałe operacje dotyczące formatu Portable Document Format (PDF) poza obsługę żądania, korzystając z kolejki CodeIgniter 4 Queue.
Przegląd koncepcyjny
Dział zatytułowany „Przegląd koncepcyjny”CodeIgniter 4 rozwiązuje usługi pakietu za pomocą własnego lokatora. We wzorcu service locator obiekt otrzymuje kontener i używa go do pobierania własnych zależności. Wytyczne PHP Standard Recommendation (PSR) odradzają ten wzorzec (PSR-11 §1.3, czasownik modalny SHOULD NOT). Aby zastosować się do tych wytycznych, rozwiąż każdą usługę NextPDF jednokrotnie na granicy kontrolera, a następnie przekaż dalej konkretny obiekt. Nie przekazuj klasy Services ani kontenera do kodu domeny.
W każdym przykładzie PHP declare(strict_types=1); znajduje się w osobnym wierszu (PSR-12 §x1.x3.p34).
Powierzchnia API
Dział zatytułowany „Powierzchnia API”| Zagadnienie produkcyjne | Zweryfikowana powierzchnia |
|---|---|
| Rozwiązywanie usług | Services::pdf(false), Services::pdfDocument(false), Services::documentFactory() |
| Budowanie odpowiedzi | PdfResponse::download() / inline() → DownloadResponse |
| Przechwytywanie błędów | NextPDF\Exception\NextPdfException (typ bazowy ekosystemu) |
| Generowanie asynchroniczne | GeneratePdfJob zarejestrowane w Config\Queue::$jobHandlers |
| Zabezpieczenia ścieżek / wywoływalnych | GeneratePdfJob zgłasza InvalidArgumentException |
Kontroler produkcyjny — obsługa błędów i obserwowalność
Dział zatytułowany „Kontroler produkcyjny — obsługa błędów i obserwowalność”Wszystkie wyjątki zgłaszane przez silnik podstawowy rozszerzają NextPDF\Exception\NextPdfException. Przechwyć ten jeden typ, aby objąć błędy rdzenia i rozszerzeń. Ten blok catch rejestruje kontekst i zwraca zdefiniowaną odpowiedź błędu; nigdy nie jest pusty.
<?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]); } }}Przy każdym wywołaniu Services::pdf(false) zwraca nową instancję biblioteki i nowy dokument bazowy. Współbieżne żądania nigdy nie współdzielą stanu dokumentu. Testy funkcjonalne pakietu potwierdzają to zachowanie.
Cykle życia usług bezpieczne dla procesów roboczych
Dział zatytułowany „Cykle życia usług bezpieczne dla procesów roboczych”Rejestry czcionek i obrazów są z założenia singletonami o cyklu życia procesu. Rejestr czcionek jest rozgrzewany i blokowany jednorazowo. Rejestr obrazów to ograniczona pamięć podręczna typu least recently used (LRU). W długo działającym procesie roboczym (serwer CodeIgniter spark, mechanizm uruchomieniowy w stylu RoadRunner lub proces roboczy kolejki) jest to zamierzone: kosztowne rejestry pozostają w pamięci, podczas gdy każdy dokument jest nowy. Nie pobieraj współdzielonego dokumentu (Services::pdfDocument(true)) w kodzie żądania ani zadania; służy on wyłącznie do resetowania testów i powodowałby współdzielenie zawartości między żądaniami.
Generowanie asynchroniczne z CodeIgniter Queue
Dział zatytułowany „Generowanie asynchroniczne z CodeIgniter Queue”GeneratePdfJob uruchamia generowanie PDF poza obsługą żądania za pomocą codeigniter4/queue. Środowisko uruchomieniowe kolejki wymaga dwóch elementów konfiguracji. Skonfiguruj oba poprawnie.
1. Zarejestruj procedurę obsługi zadania według nazwy
Dział zatytułowany „1. Zarejestruj procedurę obsługi zadania według nazwy”Kolejka rozwiązuje zadanie według klucza nazwy, a nie według ciągu znaków klasy. Procedura obsługi kolejki porównuje nazwę dodawanego zadania z kluczami Config\Queue::$jobHandlers. Odrzuca nieznaną nazwę, zgłaszając CodeIgniter\Queue\Exceptions\QueueException. Zarejestruj zadanie w pliku 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. Wysyłaj zadanie pod zarejestrowaną nazwą
Dział zatytułowany „2. Wysyłaj zadanie pod zarejestrowaną nazwą”Dodaj zadanie do kolejki, podając zarejestrowaną nazwę jako drugi argument. Pierwszy argument to nazwa kolejki. Trzeci argument to tablica danych zadania.
<?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. Zaimplementuj builder w przestrzeni nazw App\PdfBuilders
Dział zatytułowany „3. Zaimplementuj builder w przestrzeni nazw App\PdfBuilders”Zadanie dopuszcza wywoływalne buildery tylko w przestrzeni nazw App\PdfBuilders i ogranicza ścieżki wyjściowe do WRITEPATH/pdfs/. Zaimplementuj builder jako metodę statyczną. Builder otrzymuje nowy obiekt Document oraz tablicę kontekstu, a następnie zwraca dokument.
<?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; }}Uruchom proces roboczy
Dział zatytułowany „Uruchom proces roboczy”php spark queue:work pdf-queueKażde uruchomienie zadania rozpoczyna się od nowego dokumentu z Services::pdfDocument(). Zadanie stosuje builder, a następnie zapisuje wynik do zweryfikowanej ścieżki. Testy pakietu weryfikują, że dwa kolejne uruchomienia zadania nie współdzielą stanu dokumentu.
Przypadki brzegowe i pułapki
Dział zatytułowany „Przypadki brzegowe i pułapki”- Kolejka odrzuca
GeneratePdfJob::classjako nazwę zadania podczas dodawania, ponieważ nie jest to zarejestrowany klucz'generate-pdf'. Zawsze używaj klucza zjobHandlers. - Ciąg znaków buildera musi dokładnie pasować do
App\PdfBuilders\<Class>::<method>. Funkcje, inne przestrzenie nazw lub ładunki z przedrostkiem albo przyrostkiem powodują zgłoszenieInvalidArgumentException, zanim wykona się jakikolwiek kod. - Ścieżka wyjściowa musi rozwiązywać się wewnątrz
WRITEPATH/pdfs/i kończyć się rozszerzeniem.pdf(bez rozróżniania wielkości liter). Ścieżki z przechodzeniem katalogów oraz z prefiksem katalogu siostrzanego są odrzucane. codeigniter4/queuejest w pakiecie zależnością wyłącznie deweloperską. Dołącz ją w aplikacji, która uruchamia procesy robocze.
Wydajność
Dział zatytułowany „Wydajność”Rejestry są tworzone raz na proces roboczy. Koszt budowania dokumentu skaluje się wraz z zawartością, a nie z adapterem. W przypadku dużych zadań wsadowych użyj kolejki, aby procesy robocze obsługujące żądania pozostawały responsywne. Ustaw performance_budget dla każdego przepisu z mierzalnym celem.
Uwagi dotyczące bezpieczeństwa
Dział zatytułowany „Uwagi dotyczące bezpieczeństwa”Zadanie w kolejce jest powierzchnią o najwyższym ryzyku. Gdy broker jest dostępny, atakujący może kształtować ładunki kolejki. Lista dozwolonych wywoływalnych oraz ograniczanie ścieżek są omówione w /integrations/codeigniter/security-and-operations/ wraz ze zweryfikowanymi przypadkami odrzucenia.
Zgodność
Dział zatytułowany „Zgodność”- Kontrolery otrzymują konkretne usługi, a nie kontener, zgodnie z wytycznymi PSR-11 §1.3 dotyczącymi wzorca service locator.
Kontekst komercyjny
Dział zatytułowany „Kontekst komercyjny”Rdzeń NextPDF jest na licencji Apache-2.0. Aby w zadaniach kolejki tworzyć podpisane wyniki oraz wyniki w formacie PDF/A, zainstaluj NextPDF Pro lub Enterprise w środowisku procesu roboczego. Pakiet CodeIgniter udostępnia odpowiadające metody usług. Zwracają null, dopóki nie zostanie zainstalowany odpowiedni pakiet Premium. Zobacz </get-license/?intent=codeigniter-async-signing>.
Zobacz też
Dział zatytułowany „Zobacz też”- /integrations/codeigniter/quickstart/ — minimalna wersja tych kontrolerów.
- /integrations/codeigniter/configuration/ — podpisywanie, urząd znakowania czasem (TSA) oraz konfiguracja ścieżek.
- /integrations/codeigniter/security-and-operations/ — model zagrożeń kolejki i utwardzanie zabezpieczeń.
- /integrations/codeigniter/troubleshooting/ — tryby awarii kolejki i ich wykrywanie.
- /integrations/codeigniter/integration/ — odniesienie do połączeń oraz test dymny.