Pro 에디션
템플릿
한눈에 보기
섹션 제목: “한눈에 보기”NextPDF\Pro\Template는 JSON 템플릿 정의를 타입이 지정된 값 객체로
파싱하고, 연관 데이터 배열을 타입 인식 포맷팅으로 그 placeholder에
바인딩합니다. 구조화된 바인딩 결과를 생성하며, PDF 자체를 렌더링하지는
않습니다.
가용성 및 라이선싱
섹션 제목: “가용성 및 라이선싱”이 기능은 NextPDF Pro(nextpdf/pro)에 포함되며 Pro 등급 라이선스
봉투로 활성화됩니다. 해당 엔타이틀먼트가 없는 배포는 이 기능의 클래스를
로드하지 않습니다. 이 모듈을 게이팅하는 추가 런타임 기능 플래그는 등급
라이선스 외에 없습니다.
에디션을 비교하고 라이선스를 받으십시오.
composer require nextpdf/pro:^3개념 개요
섹션 제목: “개념 개요”템플릿은 페이지 설정과 위치가 지정된 placeholder 목록을 기술하는 JSON
문서입니다. TemplateParser는 JSON을 검증하고 불변 TemplateDefinition을
생성합니다. 검증은 엄격합니다. 페이지 크기를 허용 목록(A3–A6, B4, B5,
Letter, Legal, Tabloid)에 대해 검사하고, 방향(P 또는 L), 그리고 각
placeholder의 이름, 타입, 숫자 좌표를 검사하며, 중복 placeholder 이름을
거부합니다.
TemplateDataBinder는 데이터 배열(placeholder 이름에 대소문자 구분 없이
매칭됨)을 바인딩하고 각 값을 PlaceholderType별로 포맷합니다.
- Text / Image / Barcode — 값이 문자열로 그대로 전달됩니다.
- Date — placeholder의 형식(기본값
Y-m-d)으로 포맷되며, 문자열, Unix 타임스탬프, 또는DateTimeInterface를 허용합니다. - Number — 형식에서 가져온 소수 자릿수(기본값 2)로
number_format을 적용합니다. - Currency — format 문자열을 접두사로 하여 포맷된 숫자입니다
(기본값
$). - Conditional — 진릿값(truthiness)에 따라
"true"또는"false"입니다.
결과는 바인딩된 값, 누락된 필수 필드 목록, 그리고 포맷팅 경고를 담는
BindingResult입니다. 바인딩된 값을 렌더링된 PDF로 바꾸는 것은 Core
document 및 writer API와 선택적 backgroundPdf 참조를 사용하는 호출자의
책임입니다.
이렇게 동작하는 이유
섹션 제목: “이렇게 동작하는 이유”파서가 유일한 권위 있는 게이트입니다. 신뢰할 수 없는 JSON을 불변이며
완전히 타입이 지정된 TemplateDefinition으로 바꾸고, 이후 바인딩은 그 값의
순수 함수로 실행됩니다. 나중에 포맷팅 싱크에 도달하는 모든 필드는 파싱
시점에 허용 목록화되고 길이가 제한됩니다. 페이지 크기, 방향, 숫자 정밀도,
제어 문자는 모두 렌더링 도중이 아니라 여기서 실패합니다. 문자열 date는
고정된 정규 형식 집합에 대해 매칭되므로 now나 +1 year 같은 값이 출력을
벽시계 시각에 의존하게 만들 수 없습니다. 이 모듈은 의도적으로
BindingResult에서 멈추고 렌더링, 경로 해석, 배경 합성은 호출자에게
남겨 두어 신뢰 경계를 명시적으로 유지합니다.
설계 배경: 인보이스와 e-인보이싱.
동작 계약
섹션 제목: “동작 계약”- 입력. JSON 문자열(
TemplateParser)과 데이터 배열 (TemplateDataBinder). - 출력. 파싱에서
TemplateDefinition; 바인딩에서BindingResult. - 검증.
validate()는 사람이 읽을 수 있는 오류 목록을 반환하며 결코 던지지 않습니다.parse()는 검증이 실패하면InvalidArgumentException을 던집니다. - 누락 데이터. 데이터가 없고 기본값이 빈 placeholder는
missingFields에 보고됩니다. 비어 있지 않은 기본값이 있는 placeholder는 기본값을 사용합니다. - 결정성. 파싱과 바인딩은 입력의 순수 함수입니다.
공개 API 표면
섹션 제목: “공개 API 표면”| 타입 | 종류 | 주요 멤버 |
|---|---|---|
NextPDF\Pro\Template\TemplateParser | final class | parse(string $json): TemplateDefinition, validate(string $json): list<string> |
NextPDF\Pro\Template\TemplateDataBinder | final class | bind(TemplateDefinition $template, array $data): BindingResult |
NextPDF\Pro\Template\TemplateDefinition | final readonly class | string $name, string $pageSize, string $orientation, array $placeholders, string $backgroundPdf, getPlaceholder(string $name): ?TemplatePlaceholder, requiredFields(): list<string> |
NextPDF\Pro\Template\TemplatePlaceholder | final readonly class | name, PlaceholderType $type, 좌표, 기본값, 형식 |
NextPDF\Pro\Template\BindingResult | final readonly class | array $bindings, array $missingFields, array $warnings |
NextPDF\Pro\Template\PlaceholderType | enum | Text, Image, Barcode, Date, Number, Currency, Conditional; requiresFormatting(): bool |
코드 샘플 — 빠른 시작
섹션 제목: “코드 샘플 — 빠른 시작”<?php
declare(strict_types=1);
use NextPDF\Pro\Template\TemplateDataBinder;use NextPDF\Pro\Template\TemplateParser;
$json = '{"name":"Invoice","pageSize":"A4","orientation":"P","placeholders":' . '[{"name":"total","type":"currency","x":400,"y":700,"width":120,' . '"height":18,"format":"$"}]}';
$template = (new TemplateParser())->parse($json);$result = (new TemplateDataBinder())->bind($template, ['total' => 1299.5]);
foreach ($result->bindings as $bound) { echo $bound->placeholder->name, ' => ', $bound->formattedValue, "\n";}코드 샘플 — 프로덕션
섹션 제목: “코드 샘플 — 프로덕션”<?php
declare(strict_types=1);
use NextPDF\Pro\Template\TemplateDataBinder;use NextPDF\Pro\Template\TemplateParser;
function bindOrReject(string $json, array $data): array{ $parser = new TemplateParser();
$errors = $parser->validate($json); if ($errors !== []) { throw new InvalidArgumentException(implode('; ', $errors)); }
$template = $parser->parse($json); $result = (new TemplateDataBinder())->bind($template, $data);
if ($result->missingFields !== []) { throw new RuntimeException( 'missing required fields: ' . implode(', ', $result->missingFields), ); }
return $result->bindings; // hand to the renderer}엣지 케이스 및 함정
섹션 제목: “엣지 케이스 및 함정”- 파싱 불가능한 date 문자열은 경고를 생성하고 원래 문자열이 유지되며, 던지지 않습니다.
- currency 형식 문자열은 로케일 식별자가 아니라 리터럴 접두사로
사용됩니다(예:
"$"또는"EUR "). backgroundPdf는 정의에 담긴 경로 참조입니다. 이 모듈은 이를 열거나, 검증하거나, 합성하지 않습니다. 그것은 렌더러의 작업입니다.- placeholder 이름은 대소문자 구분 없이 매칭됩니다. JSON의 중복 이름은 검증 오류입니다.
파싱은 JSON 디코드 1회에 구조적 검증을 더한 것입니다. 바인딩은 placeholder
수에 선형적입니다. performance_budget을 참고하십시오.
보안 참고
섹션 제목: “보안 참고”JSON은 JSON_THROW_ON_ERROR로 디코딩되며, TemplateDefinition이
구성되기 전에 고정 허용 목록에 대해 검증됩니다. 이 모듈은 파일이나 네트워크
I/O를 수행하지 않습니다. backgroundPdf 경로는 여기서 역참조되지 않으므로,
경로 처리와 접근 제어는 렌더러에 속합니다.
적합성
섹션 제목: “적합성”이 모듈에는 직접적인 PDF 명세 표면이 없습니다. JSON 템플릿을 파싱하고 값을 포맷합니다. 페이지 크기와 방향 어휘는 규범적 PDF 구성물이 아니라 NextPDF 규약입니다.
Core 폴백 / 대안
섹션 제목: “Core 폴백 / 대안”Core 템플릿 정의 계층은 없습니다. 완전히 명령형(imperative)인 문서 구성에는 오픈 소스 Core document 및 writer API를 직접 사용하십시오. /modules/core/document/를 참고하십시오.
Enterprise 경계 참고
섹션 제목: “Enterprise 경계 참고”이 모듈은 템플릿을 정의하고 바인딩합니다. 메일 머지 조율, 배치 작업 스케줄링, 렌더링은 수행하지 않습니다. 그러한 사안은 범위 밖이며 다른 곳에서 처리됩니다.
게시 경계
섹션 제목: “게시 경계”이 페이지는 외부에서 관찰 가능한 동작과 지원되는 공개 API 표면만 설명합니다. 내부 네임스페이스 경로, 헬퍼 클래스, 메커니즘 표, 런북 파일명, 티켓 접두사는 범위 밖입니다.