빠른 시작 — 첫 엣지 렌더링
한눈에 보기
섹션 제목: “한눈에 보기”이 페이지에서는 단일 HTML 문자열을 PDF 파일로 변환합니다. 여기에서 다루는 모든 호출은 메서드에 대응하며, 각 메서드의 동작은 tests/Unit/Cloudflare/CloudflareHtmlRendererTest.php에서 검증됩니다.
사전 요구 사항
섹션 제목: “사전 요구 사항”- HTTPS를 통해 렌더 계약을 제공하는 Worker 엔드포인트.
- Worker가 수락하는 bearer 토큰.
- 경로에 준비된 PSR-18 클라이언트와 PSR-17 팩토리(/integrations/cloudflare/install/ 참조).
CloudflareResponseParser가 관찰하는 Worker 계약은 성공 시 HTTP 200을 반환하는 것입니다. 응답은 Content-Type: application/pdf(원시 PDF 바이트) 또는 base64 pdf 필드가 포함된 Content-Type: application/json 중 하나입니다. 200이 아닌 모든 상태 또는 %PDF 마커로 시작하지 않는 본문은 실패로 처리됩니다.
1 단계 — 구성 생성
섹션 제목: “1 단계 — 구성 생성”<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Cloudflare\CloudflareRendererConfig;
$config = new CloudflareRendererConfig( workerUrl: 'https://pdf-renderer.example.workers.dev/render', apiToken: getenv('CF_PDF_TOKEN') ?: throw new RuntimeException('CF_PDF_TOKEN not set'),);토큰은 환경 변수에서 읽고 하드코딩하지 않습니다. workerUrl은 HTTPS여야 합니다. http:// URL을 전달하면 브리지는 요청을 전송하기 전에 이를 Worker URL must use HTTPS로 거부합니다.
2 단계 — 렌더러 빌드
섹션 제목: “2 단계 — 렌더러 빌드”use GuzzleHttp\Client;use GuzzleHttp\Psr7\HttpFactory;use NextPDF\Cloudflare\CloudflareHtmlRenderer;
$httpFactory = new HttpFactory();
$renderer = new CloudflareHtmlRenderer( config: $config, httpClient: new Client(), // PSR-18 ClientInterface requestFactory: $httpFactory, // PSR-17 RequestFactoryInterface streamFactory: $httpFactory, // PSR-17 StreamFactoryInterface logger: null, // optional PSR-3 LoggerInterface responseFactory: $httpFactory, // PSR-17; enables the pinned transport);생성자에는 구성, PSR-18 클라이언트, 요청 팩토리, 스트림 팩토리라는 네 개의 인수가 필요합니다. 추가로 네 개의 인수를 선택적으로 전달할 수 있습니다. 로거, 로컬 렌더러 팩토리, 명시적 HTML 보안 정책, 응답 팩토리입니다. 응답 팩토리를 제공하면 확인된 IP 집합 또는 SPKI 핀 집합이 있을 때 고정된 cURL 전송이 활성화됩니다(/integrations/cloudflare/security-and-operations/ 참조).
3 단계 — 렌더링 및 기록
섹션 제목: “3 단계 — 렌더링 및 기록”use NextPDF\Cloudflare\Exception\CloudflareNotAvailableException;use NextPDF\Cloudflare\Exception\CloudflareRenderException;
try { $result = $renderer->render('<h1>Hello from the edge</h1>');
if (!$result->isValid()) { throw new RuntimeException('Worker did not return a valid PDF'); }
file_put_contents('output.pdf', $result->pdfData); printf("Wrote %d bytes from edge %s in %.1f ms\n", $result->size(), $result->renderLocation !== '' ? $result->renderLocation : 'unknown', $result->renderTimeMs, );} catch (CloudflareRenderException $e) { // Worker answered but the render failed (HTTP error or malformed body). fwrite(STDERR, 'Render failed: ' . $e->getMessage() . PHP_EOL); exit(1);} catch (CloudflareNotAvailableException $e) { // Worker unreachable and no usable fallback. fwrite(STDERR, 'Edge unavailable: ' . $e->getMessage() . PHP_EOL); exit(2);}render()는 기본적으로 A4 너비(595.28 PDF 포인트)와 자동 감지 높이(heightPt: 0)를 사용합니다. 두 예외 유형은 의도적으로 구분됩니다. CloudflareRenderException은 Worker 측 실패이며, 폴백으로 재시도되지 않습니다. CloudflareNotAvailableException은 엣지에 도달할 수 없고 사용 가능한 로컬 폴백이 없음을 의미합니다.
4 단계 — 결과 검사
섹션 제목: “4 단계 — 결과 검사”CloudflareRenderResult는 final readonly입니다. 다음 필드는 바이너리 경로에서는 응답 헤더에서, JSON 경로에서는 JSON 필드에서 채워집니다.
| 멤버 | 소스 |
|---|---|
pdfData | 원시 PDF 바이트 |
widthPt | 요청한 너비 |
heightPt | X-Pdf-Height-Pt 헤더 / JSON heightPt. 없거나 양수가 아니면 841.89(A4 높이)으로 기본 설정됩니다 |
contentHeightPx | X-Content-Height-Px / JSON contentHeightPx |
renderLocation | CF-Ray 헤더 접미사(바이너리 경로) 또는 JSON renderLocation에서 파생됩니다 |
renderTimeMs | X-Render-Time-Ms / JSON renderTimeMs |
size() | strlen($pdfData) |
isValid() | 바이트가 %PDF로 시작할 때 true |
선택 사항 — 사용자 지정 용지 크기, 글꼴, CSS
섹션 제목: “선택 사항 — 사용자 지정 용지 크기, 글꼴, CSS”$result = $renderer->render( html: '<div style="font-family: NotoSansCJK;">繁體中文文件</div>', widthPt: 595.28, heightPt: 841.89, // explicit A4; 0 lets the Worker auto-detect fontFiles: ['NotoSansCJKtc-Regular.ttf'],);fontFiles는 구성에서 r2FontBucket을 설정한 경우에만 의미가 있습니다. 이때 페이로드가 버킷 이름과 요청된 글꼴 파일 경로를 전달하므로 Worker가 이를 로드할 수 있습니다.
선택 사항 — 도달성 프로브
섹션 제목: “선택 사항 — 도달성 프로브”if ($renderer->isAvailable()) { $result = $renderer->render($html);}isAvailable()는 Worker URL로 인증된 HTTP HEAD를 전송합니다. 상태가 500 미만이면 true를 반환합니다. 구성이 잘못되었거나 요청이 실패할 때는 throw 없이 false를 반환합니다. 이를 보장이 아닌 힌트로 취급하십시오. Worker는 후속 POST에서 여전히 실패할 수 있습니다.
관련 항목
섹션 제목: “관련 항목”- /integrations/cloudflare/production-usage/ — 폴백 연결, 텔레메트리, R2 아카이브.
- /integrations/cloudflare/troubleshooting/ — 각 예외와 메시지에 매핑되는 모든 실패.
- /integrations/cloudflare/configuration/ — 전체 필드 레퍼런스.