Przejdź do głównej zawartości

NextPDF dla CodeIgniter 4

nextpdf/codeigniter łączy silnik NextPDF dla formatu Portable Document Format (PDF) z aplikacją CodeIgniter 4 przez warstwę Services frameworka. Dokumenty PDF tworzysz w kontrolerach, zadaniach lub poleceniach, a następnie zwracasz je jako natywne odpowiedzi protokołu Hypertext Transfer Protocol (HTTP) w CodeIgniter.

Okno terminala
composer require nextpdf/codeigniter

Plik composer.json pakietu wymaga php >=8.4 <9.0, nextpdf/core ^3.0 || ^5.2 oraz codeigniter4/framework ^4.6. Sugeruje również nextpdf/artisan, nextpdf/premium oraz codeigniter4/queue. Pełną tabelę wymagań, pakiety opcjonalne oraz kroki weryfikacji znajdziesz na stronie /integrations/codeigniter/install/.

NextPDF to silnik PDF 2.0 napisany w PHP 8.4. Podstawowy silnik (nextpdf/core) jest niezależny od frameworka. Nie zna protokołu HTTP, routingu ani mechanizmów wiązania zależności. nextpdf/codeigniter to adapter, który łączy silnik z aplikacją CodeIgniter 4. Po zainstalowaniu adaptera nie musisz samodzielnie wiązać rejestrów, fabryk ani obsługi odpowiedzi.

Pakiet dodaje do aplikacji CodeIgniter 4 cztery elementy:

  • Klasę Services (NextPDF\CodeIgniter\Config\Services), którą CodeIgniter wykrywa automatycznie. Udostępnia nazwane usługi: fontRegistry, imageRegistry, documentFactory, pdfDocument, pdf, tsaClient oraz pdfSigner.
  • Bibliotekę Pdf (NextPDF\CodeIgniter\Libraries\Pdf) — wysokopoziomowy interfejs programowania aplikacji (API) dla kontrolerów. Opakowuje pojedynczy, jednorazowy dokument i jednym wywołaniem zamienia go w odpowiedź.
  • Pomocnik PdfResponse (NextPDF\CodeIgniter\Http\PdfResponse), który tworzy obiekt DownloadResponse frameworka CodeIgniter do podglądu w przeglądarce lub pobrania. Dołącza stały zestaw nagłówków zwiększających bezpieczeństwo odpowiedzi.
  • Dwie globalne funkcje pomocnicze, pdf() oraz pdf_document(). Są rejestrowane przez wpis autoload files w Composerze oraz klasę Registrar pakietu.

Podczas tworzenia dokumentu pakiet wykrywa też opcjonalne rozszerzenia NextPDF. Jeśli zainstalowany jest nextpdf/artisan i skonfigurowany jest plik wykonywalny Chrome, dokument otrzymuje renderer Chrome. Jeśli zainstalowany jest NextPDF Pro, wyjście PDF/A oraz podpisywanie cyfrowe są dostępne przez tę samą warstwę Services. Wykrywanie działa warunkowo i cicho. Pakiet nigdy nie wymaga rozszerzenia, którego nie ma.

CodeIgniter 4 nie dostarcza kontenera wstrzykiwania zależności PSR-11. Zamiast tego korzysta z lokalizatora Services. Lokalizator Services to wykrywana przez framework klasa ze statycznymi metodami fabrycznymi. Każda metoda zwraca instancję współdzieloną lub nową. W PSR-11 §1.3, z czasownikiem modalnym SHOULD NOT, odradzono wzorzec lokalizatora usług — przekazywanie kontenera do obiektu, aby ten sam pobierał swoje zależności. Pakiet stosuje się do konwencji lokalizatora frameworka CodeIgniter. Zachowuje też minimalną i jawną powierzchnię lokalizatora: każda usługa to nazwana metoda fabryczna z parametrem bool $getShared, a wywołujący otrzymują konkretne obiekty zamiast uchwytu do kontenera.

Taki projekt zachowuje spójność integracji CodeIgniter z integracjami Laravel i Symfony. Każda integracja udostępnia te same logiczne usługi w idiomie swojego frameworka.

Punkt wejściaTypZwracaCzas życia
Services::fontRegistry()usługaFontRegistryInterfacewspółdzielona (rozgrzana, potem zablokowana)
Services::imageRegistry()usługaImageRegistrywspółdzielona (ograniczona pamięć podręczna typu least recently used (LRU))
Services::documentFactory()usługaDocumentFactoryInterfacewspółdzielona (bezstanowa)
Services::pdfDocument(false)usługaNextPDF\Core\Documentnowa przy każdym wywołaniu
Services::pdf(false)usługaNextPDF\CodeIgniter\Libraries\Pdfnowa przy każdym wywołaniu
Services::tsaClient()usługa?TsaClientwspółdzielona; null, gdy brak adresu URL urzędu znacznika czasu (TSA)
Services::pdfSigner(false)usługa?SignerInterfacenowa; null, gdy podpisywanie wyłączone
pdf()pomocnikPdfnowa przy każdym wywołaniu
pdf_document()pomocnikDocumentnowa przy każdym wywołaniu
PdfResponse::inline() / download()statycznaDownloadResponsena wywołanie
GeneratePdfJobzadanie kolejkijedno na wysłanie

Kontroler zwraca PDF w trzech wierszach. Services::pdf() zwraca nową bibliotekę Pdf, która opakowuje nowy dokument. Następnie download() tworzy obiekt DownloadResponse frameworka CodeIgniter.

<?php
declare(strict_types=1);
namespace App\Controllers;
use CodeIgniter\HTTP\DownloadResponse;
use NextPDF\CodeIgniter\Config\Services;
final class InvoiceController extends BaseController
{
public function download(int $id): DownloadResponse
{
$pdf = Services::pdf();
$pdf->document()->addPage();
$pdf->document()->cell(0, 10, "Invoice #{$id}");
return $pdf->download("invoice-{$id}.pdf");
}
}

Pełny przewodnik gotowy do uruchomienia znajduje się na stronie /integrations/codeigniter/quickstart/. Obejmuje routing, podgląd w przeglądarce oraz warianty z pomocnikami pdf() oraz pdf_document().

W środowisku produkcyjnym pobierz instancję niewspółdzieloną za pomocą Services::pdf(false). Obsłuż jeden bazowy wyjątek, NextPDF\Exception\NextPdfException; dziedziczą po nim wszystkie wyjątki awarii silnika i rozszerzeń. Rejestruj awarię wraz z kontekstem, zamiast po cichu połykać błąd.

try {
$pdf = Services::pdf(false);
$pdf->document()->addPage();
$pdf->document()->cell(0, 10, "Invoice #{$id}");
return $pdf->download("invoice-{$id}.pdf");
} 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]);
}

Kompletny produkcyjny kontroler znajduje się na stronie /integrations/codeigniter/production-usage/. Dodaje pomiar czasu na potrzeby obserwowalności, czasy życia bezpieczne dla workerów oraz generowanie asynchroniczne.

  • Rejestry czcionek i obrazów to singletony o czasie życia procesu. Dokument nigdy nie jest współdzielony. pdfDocument oraz pdf przy każdym wywołaniu zwracają nową instancję, więc zawartość jednego żądania nie może wyciec do innego. Services::pdf(false) oraz pdf() zwracają nową bibliotekę, która opakowuje nowy dokument.
  • Pakiet wymaga rozszerzeń PHP mbstring oraz zlib. Rejestr czcionek waliduje je raz na proces. Jeśli któregoś rozszerzenia brakuje, rejestr czcionek zgłasza błąd czasu wykonania, który wskazuje brakujące rozszerzenie.
  • Zachowanie opcjonalnych rozszerzeń zależy od tego, co jest zainstalowane w tej samej aplikacji. Gdy obecny jest tylko nextpdf/core, ścieżki podpisywania i PDF/A zwracają null albo są pomijane. Nigdy nie kończą się głośną awarią.

Integracja nie dodaje żadnego mierzalnego narzutu poza samym silnikiem. Rejestr czcionek jest parsowany raz, a następnie blokowany. Rejestr obrazów to pamięć podręczna LRU ograniczona ustawieniem imageCacheMb (domyślnie 50 MB). O koszcie budowania PDF decydują podstawowy silnik i zawartość dokumentu, a nie adapter. Budżet na stronę dla tego zestawu dokumentacji to 1500 ms czasu zegarowego / 128 MB szczytowo. Rzeczywiste receptury ustalają własny budżet w nagłówku frontmatter.

PdfResponse dołącza stały zestaw nagłówków odpowiedzi do każdego emitowanego pliku PDF: X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Content-Security-Policy: default-src 'none', X-Robots-Tag: noindex, nofollow oraz Referrer-Policy: no-referrer. Nazwy plików są oczyszczane, a nazwy spoza ASCII są emitowane z rozszerzonym parametrem Request for Comments (RFC) 5987. Zadanie kolejki ogranicza możliwe do wywołania buildery do przestrzeni nazw App\PdfBuilders i zawęża ścieżki wyjściowe do WRITEPATH/pdfs/. Pełny model zagrożeń znajdziesz na stronie /integrations/codeigniter/security-and-operations/.

  • Wykrywanie modułów opiera się na autoładowaniu PSR-4 w Composerze. Prefiks przestrzeni nazw jest odwzorowywany na katalog bazowy, a w pełni kwalifikowana nazwa klasy na ścieżkę pliku (PSR-4 §x1.x3).
  • Projekt Services kieruje się wytycznymi dotyczącymi lokalizatora omówionymi w PSR-11 §1.3.

Rdzeń NextPDF jest udostępniany na licencji Apache-2.0. Podpisy cyfrowe, archiwizację PDF/A oraz osadzanie e-faktur Factur-X zapewniają NextPDF Pro i NextPDF Enterprise. Pakiet CodeIgniter udostępnia odpowiadające im metody usługowe. Te metody zwracają null, dopóki w tej samej aplikacji nie zostanie zainstalowany odpowiedni pakiet Premium.

  • /integrations/codeigniter/install/ — instalacja i weryfikacja pakietu.
  • /integrations/codeigniter/quickstart/ — pierwszy PDF w kontrolerze.
  • /integrations/codeigniter/configuration/ — każdy klucz konfiguracji.
  • /integrations/codeigniter/boot-and-discovery/ — jak CodeIgniter znajduje klasę Services.
  • /integrations/codeigniter/integration/ — referencja powiązań i test dymny.