콘텐츠로 이동

Artisan 개발자 가이드

Artisan 패키지는 서로 연결된 두 가지 책임을 가집니다. Chrome을 통해 HTML을 렌더링하고, 그 결과로 생성된 PDF 페이지를 NextPDF 문서로 가져옵니다. 디버깅할 때는 Chrome, 파서, 임포터 경계를 각각 분리해서 다루십시오.

이 가이드는 nextpdf/artisan을 기반으로 렌더러 통합, 장기 실행 워커, 파서 진단 또는 테스트를 작성할 때 사용하십시오.

계층소유 주체책임여기에 두지 말아야 할 것
애플리케이션애플리케이션HTML 생성을 승인하고 렌더러 구성을 선택합니다.브라우저 프로세스 관리.
HTML 정책애플리케이션 및 패키지렌더링 전에 안전하지 않거나 크기가 과도한 HTML을 거부합니다.테넌트 승인 또는 비즈니스 결정.
Chrome 렌더러nextpdf/artisanChrome을 사용해 HTML을 독립 실행형 PDF로 렌더링합니다.일반적인 PDF 복구 또는 임의의 PDF 편집.
파서/임포터nextpdf/artisan렌더링된 PDF를 파싱하고 한 페이지를 form XObject로 가져옵니다.전체 PDF 적합성 검증.
코어 엔진nextpdf/nextpdf가져온 form 객체를 배치하고 최종 문서를 작성합니다.Chrome CDP 수명 주기.
단계동작개발자 조치
구성 생성ChromeRendererConfig는 바이너리, 타임아웃, CSS, 입력 크기, 샌드박스 동작을 정의합니다.하드코딩된 런타임 가정 대신 환경별 구성을 사용하십시오.
렌더러 생성ChromeHtmlRendererBrowserPool을 소유합니다.워커 내부에서 렌더러를 재사용하고, 종료 시 닫으십시오.
HTML 검증보안 정책이 크기를 확인하고 문서를 기본 CSS로 래핑합니다.이 단계 전에 호출자 권한을 검증하십시오.
Chrome 인쇄CDP가 독립 실행형 PDF를 렌더링합니다.검토된 정책으로 허용한 경우가 아니면 외부 리소스를 차단 상태로 유지하십시오.
PDF 파싱PdfReader::parse()는 xref 데이터, 페이지, 객체, 리소스, 리비전을 읽습니다.진단이 목적이 아닌 한 파서 실패를 렌더링 실패로 처리하십시오.
페이지 가져오기PageImporter::import()는 페이지 콘텐츠, 미디어 박스, 리소스, 임베디드 객체를 추출합니다.워크플로가 의도적으로 다른 페이지를 선택하지 않는 한 페이지 0을 가져오십시오.
경로용도
app/Pdf/Renderers/*ChromeHtmlRenderer를 감싸는 애플리케이션 래퍼.
app/Pdf/Templates/*HTML 템플릿 렌더링 및 DTO-뷰 매핑.
app/Pdf/Policies/*HTML 크기, 리소스, 테넌트 렌더링 정책.
tests/Pdf/Renderer/*작은 HTML 픽스처를 사용하는 렌더러 스모크 테스트.
tests/Pdf/Parser/*가져온 Chrome 출력용 파서 픽스처.

템플릿 렌더링은 브라우저 렌더링과 분리해 두십시오. 렌더러는 최종 HTML과 알려진 페이지 너비를 받아야 합니다.

<?php
use NextPDF\Artisan\ChromeHtmlRenderer;
use NextPDF\Artisan\ChromeRendererConfig;
use NextPDF\Artisan\PageImporter;
use NextPDF\Parser\PdfReader;
$renderer = new ChromeHtmlRenderer(new ChromeRendererConfig(
renderTimeout: 30,
maxHtmlSize: 1_000_000,
));
$result = $renderer->render($html, widthPt: 595.28);
$reader = new PdfReader($result->getPdfData());
$reader->parse();
$form = (new PageImporter())->import($reader);

워커 프로세스마다 또는 요청 범위마다 렌더러를 하나씩 생성하십시오. 렌더러를 재사용하면 Chrome을 반복해서 시작하는 비용을 피할 수 있습니다. 렌더러를 명시적으로 닫으면 워커 종료 중 프로세스 누수를 방지할 수 있습니다.

<?php
final class InvoiceChromeRenderer
{
public function __construct(
private readonly ChromeHtmlRenderer $renderer,
) {}
public function renderInvoice(string $html): string
{
return $this->renderer
->render($html, widthPt: 595.28)
->getPdfData();
}
public function close(): void
{
$this->renderer->close();
}
}

파서 API는 Chrome 출력 가져오기가 실패할 때 유용합니다. 진단은 읽기 전용으로 유지하고, 가져오기에 성공한 뒤에는 파서 상태를 변경하지 마십시오.

진단 질문사용할 API예상 신호
파일이 파싱됩니까?PdfReader::parse()유효하지 않은 PDF 구조이면 예외를 발생시킵니다.
페이지 0이 존재합니까?PdfReader::getPage(0)반환값은 PdfObject입니다.
콘텐츠가 있습니까?PdfReader::getPageContentStream($page)비어 있지 않은 콘텐츠 스트림.
리소스가 있습니까?PdfReader::getPageResources($page)리소스 딕셔너리 배열.
증분 리비전이 있습니까?PdfReader::getRevisionCount()개수가 1보다 큽니다.
어떤 객체가 실패했습니까?PdfTokenizer::getOffset() 및 파서 예외 컨텍스트.픽스처 축소를 위한 바이트 오프셋.
확장 지점사용 용도제약 조건
ChromeRendererConfig::fromArray()프레임워크 구성 매핑.알 수 없거나 잘못 입력된 선택적 값은 기본값으로 대체됩니다.
HtmlSecurityPolicyInterface파싱 계층의 HTML 정책.전송, 프로세스, 권한 제어를 대체하지 않습니다.
LoggerInterface렌더링 및 브라우저 진단.기본적으로 HTML 콘텐츠를 로깅하지 마십시오.
BrowserPool장기 실행 Chrome 프로세스 재사용.워커 종료 시 닫아야 합니다.
PageImporter파싱된 외부 페이지 임베딩.리더를 먼저 파싱해야 합니다.
파서 클래스진단 및 가져온 Chrome 출력 처리.일반적인 PDF 복구 툴킷이 아닙니다.
  1. 최소 렌더링 테스트로 HTML 조각을 재현하십시오.
  2. 다음을 검증하십시오: maxHtmlSize, 기본 CSS, Chrome 바이너리 경로.
  3. 포인트 단위의 고정 너비로 렌더링하십시오.
  4. 반환된 PDF 바이트를 PdfReader::parse()로 파싱하십시오.
  5. 워크플로가 의도적으로 다른 페이지를 선택하지 않는 한 페이지 0을 가져오십시오.
  6. 각 실패를 재현하는 가장 작은 HTML용 픽스처 테스트를 추가하십시오.
  7. 워커 종료 후크에서 렌더러를 닫으십시오.
실패처리되어야 할 위치권장 대응
Chrome 바이너리 누락배포 점검 및 렌더러 생성 경로.렌더링 트래픽을 수락하기 전에 준비 상태 검사에서 실패하게 하십시오.
크기 초과 HTMLHTML 정책.Chrome을 시작하기 전에 거부하십시오.
브라우저 타임아웃렌더러 경계.렌더링을 실패로 처리하고 템플릿 이름, 크기, 너비, 타임아웃을 기록하십시오.
파서 실패가져오기 경계.정책이 허용하는 경우 디버깅을 위해 작고 정제된 픽스처를 저장하십시오.
브라우저 프로세스 누수워커 수명 주기.종료 시 닫고 제어된 렌더링 횟수 후에 다시 시작하십시오.
관심사기본값재정의 시점
렌더링 타임아웃30초.측정 가능하고 범위가 제한된 문서에 대해서만 늘리십시오.
최대 HTML 크기5,000,000바이트.공개 엔드포인트의 경우 낮추십시오.
샌드박스활성화됨.컨테이너 제약 조건이 요구하고 호스트가 격리된 경우에만 비활성화하십시오.
높이값이 heightPt <= 0일 때 자동.엄격한 레이아웃 계약에는 고정 높이를 사용하십시오.
외부 리소스렌더러 정책으로 차단됨.검토된 리소스 정책을 통해서만 허용하십시오.
  • 렌더링 테스트가 대표적인 HTML과 CSS를 다룹니다.
  • 보안 테스트가 크기 초과 HTML과 차단된 리소스 시도를 다룹니다.
  • 가져오기 테스트는 반환된 form 객체에 콘텐츠, 미디어 박스, 리소스가 있는지 확인합니다.
  • 파서 테스트가 xref 테이블, xref 스트림, 객체 스트림, 잘못된 형식의 픽스처 사례를 다룹니다.
  • 워커 테스트는 close()를 호출하고 남아 있는 브라우저 프로세스가 없는지 확인합니다.
  • 성능 테스트는 템플릿 및 콘텐츠 크기별로 렌더링 시간을 기록합니다.