CodeIgniter 4용 NextPDF
한눈에 보기
섹션 제목: “한눈에 보기”nextpdf/codeigniter는 프레임워크의 Services 계층을 통해 NextPDF PDF 엔진을 CodeIgniter 4 애플리케이션에 연결합니다. 컨트롤러, 작업(job) 또는 명령에서 PDF 문서를 만든 뒤, 네이티브 CodeIgniter HTTP 응답으로 반환합니다.
composer require nextpdf/codeigniter패키지의 composer.json은 php >=8.4 <9.0,
nextpdf/core ^3.0 || ^5.2 및 codeigniter4/framework ^4.6을 필요로 합니다. 또한
nextpdf/artisan, nextpdf/premium 및 codeigniter4/queue를 제안합니다. 전체 요구 사항 표, 선택적 패키지 및 검증 단계는 /integrations/codeigniter/install/에서 확인할 수 있습니다.
개념 개요
섹션 제목: “개념 개요”NextPDF는 PHP 8.4 PDF 2.0 엔진입니다. 코어 엔진(nextpdf/core)은 프레임워크에 독립적입니다. 이 엔진은 HTTP, 라우팅 또는 의존성 연결에 대해 전혀 알지 못합니다. nextpdf/codeigniter는 이 엔진을 CodeIgniter 4 애플리케이션에 연결하는 어댑터입니다. 어댑터가 있으면 레지스트리, 팩터리 또는 응답 처리를 직접 연결하지 않아도 됩니다.
이 패키지는 CodeIgniter 4 애플리케이션에 네 가지를 추가합니다.
- Services 클래스(
NextPDF\CodeIgniter\Config\Services) — CodeIgniter가 자동으로 검색하며 다음과 같은 명명된 서비스를 노출합니다:fontRegistry,imageRegistry,documentFactory,pdfDocument,pdf,tsaClient,pdfSigner. Pdf라이브러리(NextPDF\CodeIgniter\Libraries\Pdf) — 고수준 컨트롤러 API입니다. 일회용 문서 하나를 감싸 한 번의 호출로 응답으로 변환합니다.PdfResponse헬퍼(NextPDF\CodeIgniter\Http\PdfResponse) — 인라인 미리 보기 또는 다운로드를 위한 CodeIgniterDownloadResponse를 생성합니다. 고정된 응답 강화 헤더 집합을 첨부합니다.- 두 개의 전역 헬퍼 함수인
pdf()및pdf_document()입니다. 이들은 Composerfiles자동 로드 항목과 패키지Registrar를 통해 등록됩니다.
또한 이 패키지는 문서를 빌드하는 시점에 선택적 NextPDF 확장을 감지합니다. nextpdf/artisan이 설치되고 Chrome 바이너리가 구성되면 문서는 Chrome 렌더러를 갖게 됩니다. NextPDF Pro가 설치되면 PDF/A 출력과 디지털 서명을 동일한 Services 표면을 통해 사용할 수 있습니다. 감지는 조건부로 조용히 이루어집니다. 이 패키지는 존재하지 않는 확장을 절대 요구하지 않습니다.
컨테이너 바인딩이 아닌 Services 클래스를 사용하는 이유
섹션 제목: “컨테이너 바인딩이 아닌 Services 클래스를 사용하는 이유”CodeIgniter 4는 PSR-11 의존성 주입 컨테이너를 제공하지 않습니다. 대신 Services 로케이터를 사용합니다. Services 로케이터는 프레임워크가 검색하는 정적 팩터리 메서드를 가진 클래스이며, 각 메서드는 공유 인스턴스 또는 새 인스턴스를 반환합니다. PSR-11은 서비스 로케이터 패턴 — 객체가 자체 의존성을 가져올 수 있도록 컨테이너를 객체에 전달하는 것 — 을 명시적으로 권장하지 않습니다(PSR-11 §1.3, 조동사 SHOULD NOT). 이 패키지는 CodeIgniter의 로케이터 규약을 따릅니다. 또한 로케이터 표면을 최소화하고 명시적으로 유지합니다: 모든 서비스는 bool $getShared 매개변수를 가진 명명된 팩터리 메서드이며, 호출자는 컨테이너 핸들이 아니라 구체적인 객체를 받습니다.
이 설계는 CodeIgniter 통합이 Laravel 및 Symfony 통합과 일관되도록 유지합니다. 각 통합은 자체 프레임워크의 관용 방식을 통해 동일한 논리적 서비스를 노출합니다.
API 표면
섹션 제목: “API 표면”| 진입점 | 유형 | 반환값 | 수명 |
|---|---|---|---|
Services::fontRegistry() | 서비스 | FontRegistryInterface | 공유(웜업 후 잠금) |
Services::imageRegistry() | 서비스 | ImageRegistry | 공유(크기 제한된 LRU 캐시) |
Services::documentFactory() | 서비스 | DocumentFactoryInterface | 공유(무상태) |
Services::pdfDocument(false) | 서비스 | NextPDF\Core\Document | 호출마다 새로 생성 |
Services::pdf(false) | 서비스 | NextPDF\CodeIgniter\Libraries\Pdf | 호출마다 새로 생성 |
Services::tsaClient() | 서비스 | ?TsaClient | 공유; TSA URL이 없으면 null입니다 |
Services::pdfSigner(false) | 서비스 | ?SignerInterface | 새로 생성; 서명이 비활성화된 경우 null입니다 |
pdf() | 헬퍼 | Pdf | 호출마다 새로 생성 |
pdf_document() | 헬퍼 | Document | 호출마다 새로 생성 |
PdfResponse::inline() / download() | 정적 | DownloadResponse | 호출마다 |
GeneratePdfJob | 큐 작업 | — | 디스패치마다 하나 |
코드 샘플 — 빠른 시작
섹션 제목: “코드 샘플 — 빠른 시작”컨트롤러는 세 줄로 PDF를 반환합니다. Services::pdf()는 새 문서를 감싸는 새 Pdf 라이브러리를 생성합니다. 그런 다음 download()는 CodeIgniter DownloadResponse를 생성합니다.
<?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"); }}전체 실행 가능한 안내는 /integrations/codeigniter/quickstart/에 있습니다. 여기서는 라우팅, 인라인 미리 보기 및 pdf()와 pdf_document() 헬퍼 변형을 다룹니다.
코드 샘플 — 프로덕션
섹션 제목: “코드 샘플 — 프로덕션”프로덕션에서는 Services::pdf(false)로 비공유 인스턴스를 요청해야 합니다. 단일 기본 예외 NextPDF\Exception\NextPdfException을 포착해야 합니다. 모든 코어 및 확장 실패가 이를 확장합니다. 오류를 묵살하지 말고 컨텍스트와 함께 실패를 로깅해야 합니다.
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]);}완전한 프로덕션 컨트롤러는 /integrations/codeigniter/production-usage/에 있습니다. 여기서는 관측성 타이밍, 워커에 안전한 수명 및 비동기 생성을 추가합니다.
엣지 케이스 및 주의 사항
섹션 제목: “엣지 케이스 및 주의 사항”- 글꼴 및 이미지 레지스트리는 프로세스 수명 동안 유지되는 싱글턴입니다. 문서는 절대 공유되지 않습니다.
pdfDocument와pdf는 호출할 때마다 새 인스턴스를 반환하므로, 한 요청이 다른 요청으로 콘텐츠를 유출할 수 없습니다.Services::pdf(false)와pdf()는 모두 새 문서를 감싸는 새 라이브러리를 반환합니다. - 이 패키지는
mbstring및zlibPHP 확장을 필요로 합니다. 글꼴 레지스트리는 프로세스당 한 번 이 확장들을 검증합니다. 두 확장 중 하나라도 없으면, 글꼴 레지스트리는 누락된 확장의 이름을 명시하는 런타임 오류를 발생시킵니다. - 선택적 확장 동작은 동일한 애플리케이션에 무엇이 설치되어 있는지에 따라 달라집니다.
nextpdf/core만 존재하는 경우, 서명 및 PDF/A 경로는null을 반환하거나 건너뜁니다. 이들은 절대 불필요한 오류를 내며 실패하지 않습니다.
이 통합은 엔진 자체를 넘어서는 측정 가능한 오버헤드를 추가하지 않습니다. 글꼴 레지스트리는 한 번 파싱된 후 잠깁니다. 이미지 레지스트리는 imageCacheMb 설정(기본값 50 MB)으로 크기가 제한되는 LRU 캐시입니다. PDF 빌드 비용은 어댑터가 아니라 코어 엔진과 문서 콘텐츠에 의해 결정됩니다. 이 문서 모음의 페이지당 예산은 벽시계 시간 1500 ms / 최대 128 MB입니다. 실제 레시피는 프런트 매터에서 자체 예산을 설정합니다.
보안 참고 사항
섹션 제목: “보안 참고 사항”PdfResponse는 내보내는 모든 PDF에 고정된 응답 헤더 집합을 첨부합니다: X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Content-Security-Policy: default-src 'none', X-Robots-Tag: noindex, nofollow, Referrer-Policy: no-referrer. 파일 이름은 정리되며, ASCII가 아닌 이름은 RFC 5987 확장 매개변수로 내보내집니다. 큐 작업은 빌더 콜러블을 App\PdfBuilders 네임스페이스로 제한하고, 출력 경로를 WRITEPATH/pdfs/로 한정합니다. 전체 위협 모델은 /integrations/codeigniter/security-and-operations/를 참조합니다.
적합성
섹션 제목: “적합성”- 모듈 검색은 Composer의 PSR-4 자동 로딩에 의존합니다. 네임스페이스 접두사는 기본 디렉터리에 매핑되고, 정규화된 클래스 이름은 파일 경로에 매핑됩니다(PSR-4 §x1.x3).
- Services 설계는 PSR-11 §1.3에서 논의된 로케이터 관련 지침을 따릅니다.
상업적 맥락
섹션 제목: “상업적 맥락”NextPDF 코어는 Apache-2.0입니다. 디지털 서명, PDF/A 아카이빙 및 Factur-X 전자 송장 임베딩은 NextPDF Pro와 NextPDF Enterprise에서 제공합니다. CodeIgniter 패키지는 해당 서비스 메서드를 노출합니다. 이러한 메서드는 일치하는 Premium 패키지가 동일한 애플리케이션에 설치될 때까지 null을 반환합니다.
관련 항목
섹션 제목: “관련 항목”- /integrations/codeigniter/install/ — 패키지를 설치하고 검증합니다.
- /integrations/codeigniter/quickstart/ — 컨트롤러에서의 첫 PDF입니다.
- /integrations/codeigniter/configuration/ — 모든 구성 키입니다.
- /integrations/codeigniter/boot-and-discovery/ — CodeIgniter가 Services 클래스를 찾는 방법입니다.
- /integrations/codeigniter/integration/ — 연결 참조 및 스모크 테스트입니다.