CodeIgniter 4 프로덕션 사용
한눈에 보기
섹션 제목: “한눈에 보기”프로덕션 컨트롤러는 구체적인 NextPDF 서비스에 의존합니다. 컨트롤러는 문서화된 예외 계층 구조를 명시적으로 처리하고 관측성 신호를 내보냅니다. 오래 실행되는 PDF 작업은 CodeIgniter 4 Queue를 통해 요청 처리에서 분리됩니다.
개념 개요
섹션 제목: “개념 개요”CodeIgniter 4는 로케이터를 통해 패키지의 서비스를 확인합니다. 서비스 로케이터 패턴은 객체가 스스로 의존성을 가져올 수 있도록 컨테이너를 객체에 넘기는 방식입니다. 이 패턴은 권장되지 않습니다(PSR-11 §1.3, 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 |
| 경로 / 콜러블 가드 | GeneratePdfJob이 발생시키는 InvalidArgumentException |
프로덕션 컨트롤러 — 오류 처리 및 관측성
섹션 제목: “프로덕션 컨트롤러 — 오류 처리 및 관측성”코어 엔진은 모두 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)는 호출할 때마다 새 라이브러리와 새 기반 문서를 반환합니다. 따라서 동시 요청은 결코 문서 상태를 공유하지 않습니다. 패키지 기능 테스트가 이 동작을 검증합니다.
워커에 안전한 서비스 수명
섹션 제목: “워커에 안전한 서비스 수명”글꼴 및 이미지 레지스트리는 설계상 프로세스 수명 동안 유지되는 싱글턴입니다. 글꼴 레지스트리는 한 번 워밍업된 뒤 잠깁니다. 이미지 레지스트리는 크기가 제한된 LRU(least-recently-used) 캐시입니다. 이는 수명이 긴 워커(CodeIgniter spark 서버, RoadRunner 방식 러너 또는 큐 워커)에서 의도된 동작입니다. 비용이 큰 레지스트리는 유지되고, 모든 문서는 새로 생성됩니다. 요청 코드나 작업 코드에서 공유 문서(Services::pdfDocument(true))를 요청하지 마십시오. 이 옵션은 테스트 리셋 전용이며 요청 간에 콘텐츠를 공유하게 됩니다.
CodeIgniter Queue를 사용한 비동기 생성
섹션 제목: “CodeIgniter Queue를 사용한 비동기 생성”GeneratePdfJob은 codeigniter4/queue를 통해 요청 처리와 분리된 상태에서 PDF 생성을 실행합니다. 큐 런타임은 두 가지 규칙을 강제하며, 두 가지 모두 올바르게 구성해야 합니다.
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 아래에 빌더 구현”이 작업은 빌더 콜러블을 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>와 정확히 일치해야 합니다. 함수, 다른 네임스페이스 또는 prefixed/suffixed 페이로드는 어떤 코드가 실행되기 전에InvalidArgumentException을 발생시킵니다. - 출력 경로는
WRITEPATH/pdfs/내부 경로로 해석되어야 하며.pdf로 끝나야 합니다(대소문자 구분 없음). 경로 탐색 및 형제 접두사 경로는 거부됩니다. codeigniter4/queue는 패키지의 개발 전용 의존성입니다. 워커를 실행하는 애플리케이션에서는 이를 require 하십시오.
레지스트리는 워커 프로세스당 한 번만 생성됩니다. 문서 빌드 비용은 어댑터가 아니라 콘텐츠에 따라 증가합니다. 대규모 배치 작업에서는 요청 워커가 응답성을 유지하도록 큐 경로를 우선 사용하십시오. 측정 가능한 목표가 있는 모든 레시피에는 performance_budget를 설정하십시오.
보안 참고 사항
섹션 제목: “보안 참고 사항”큐 작업은 위험도가 가장 높은 표면입니다. 공격자가 브로커에 접근할 수 있으면 큐 페이로드에 영향을 줄 수 있습니다. 콜러블 허용 목록과 경로 한정은 검증된 거부 사례와 함께 /integrations/codeigniter/security-and-operations/에서 다룹니다.
적합성
섹션 제목: “적합성”- 컨트롤러는 PSR-11 §1.3 서비스 로케이터 지침에 따라 컨테이너가 아닌 구체적인 서비스를 받습니다.
상업적 맥락
섹션 제목: “상업적 맥락”NextPDF 코어는 Apache-2.0입니다. 큐 작업에서 서명된 출력 및 PDF/A 출력을 사용하려면 워커 환경에 NextPDF Pro 또는 Enterprise가 설치되어 있어야 합니다. CodeIgniter 패키지는 해당 서비스 메서드를 노출합니다. 해당 Premium 패키지가 설치되기 전까지는 null을 반환합니다. 다음을 참조하십시오: </get-license/?intent=codeigniter-async-signing>.
함께 보기
섹션 제목: “함께 보기”- /integrations/codeigniter/quickstart/ — 이 컨트롤러의 최소 버전.
- /integrations/codeigniter/configuration/ — 서명, TSA, 경로 구성.
- /integrations/codeigniter/security-and-operations/ — 큐 위협 모델 및 강화.
- /integrations/codeigniter/troubleshooting/ — 큐 및 디스커버리 실패 모드.
- /integrations/codeigniter/integration/ — 연동 레퍼런스 및 스모크 테스트.