Cloudflare API リファレンス
NextPDF\Cloudflare パッケージは、エッジレンダリングのブリッジです。PHP プロセスが HTML を保持し、Cloudflare Worker がヘッドレスブラウザーを保持します。このパッケージは、Worker を利用する HTML レンダラー(CloudflareHtmlRenderer)とその戻り値オブジェクト、レンダリングエンドポイントを保護するリクエスト保護レイヤー(ApiProtection)、レンダリング済み PDF を保存する R2 アーカイブサービス(R2ArchiveManager)、および TLS/DNS を強化するピン留めトランスポートヘルパーを公開します。設定は 3 つの不変オブジェクト(CloudflareRendererConfig、ApiProtectionConfig、R2ArchiveConfig)にまとまっています。
まずはここから始めます。このパッケージを初めて使う場合は、CloudflareRendererConfig を作成し、CloudflareHtmlRenderer に組み込んで、render() を呼び出します。この 1 回の呼び出しで HTML が Worker に送信され、PDF バイト列を含む CloudflareRenderResult が返されます。その他のすべて(保護、アーカイブ、ピン留め)は、この 1 回の呼び出しの周りに重ねていく形になります。
よく使うタスク
「よく使うタスク」という見出しのセクション以下のスニペットは、このパッケージで最も頻繁に使われる実際のワークフローです。それぞれ自己完結しており、src/Cloudflare/ に対してソース上で検証済みで、シークレットは環境から読み込みます。
HTML 文字列をエッジで PDF にレンダリングします。これは唯一の標準的なレンダリング呼び出しです:
<?php
declare(strict_types=1);
use GuzzleHttp\Client;use GuzzleHttp\Psr7\HttpFactory;use NextPDF\Cloudflare\CloudflareHtmlRenderer;use NextPDF\Cloudflare\CloudflareRendererConfig;
$httpFactory = new HttpFactory();
$renderer = new CloudflareHtmlRenderer( config: new CloudflareRendererConfig( workerUrl: 'https://pdf-renderer.example.workers.dev/render', apiToken: getenv('CF_PDF_TOKEN') ?: throw new RuntimeException('CF_PDF_TOKEN not set'), ), httpClient: new Client(), requestFactory: $httpFactory, streamFactory: $httpFactory, responseFactory: $httpFactory,);
$result = $renderer->render('<h1>Hello from the edge</h1>', widthPt: 595.28);
if ($result->isValid()) { file_put_contents('output.pdf', $result->pdfData);}動作:HTML を HTTPS 経由で Worker に送信し、isValid() で有効な PDF であることを確認したら、返された A4 PDF バイト列をディスクに書き込みます。
レンダリング済み PDF を R2 にアーカイブし、短時間だけ有効なリンクを返します:
<?php
declare(strict_types=1);
use NextPDF\Cloudflare\R2ArchiveConfig;use NextPDF\Cloudflare\R2ArchiveManager;
$archive = new R2ArchiveManager( config: R2ArchiveConfig::fromArray([ 'bucket_name' => 'pdf-archive', 'account_id' => getenv('CF_ACCOUNT_ID') ?: '', 'access_key_id' => getenv('R2_ACCESS_KEY_ID') ?: '', 'secret_access_key' => getenv('R2_SECRET_ACCESS_KEY') ?: '', ]), httpClient: $httpClient, // PSR-18 ClientInterface requestFactory: $requestFactory, // PSR-17 RequestFactoryInterface streamFactory: $streamFactory, // PSR-17 StreamFactoryInterface);
$upload = $archive->upload($result->pdfData, 'invoice-1234.pdf');
$signedUrl = $upload->isValid() ? $archive->generateSignedUrl($upload->key, expiresInSeconds: 600) : null;動作:PDF バイト列を日付でパーティション分割した R2 キーにアップロードし、成功した場合は一時ダウンロード用に 10 分間有効な署名付き URL を発行します。
高コストな Worker 処理を行う前に、レンダリングエンドポイントを保護します:
<?php
declare(strict_types=1);
use NextPDF\Cloudflare\ApiKeyValidator;use NextPDF\Cloudflare\ApiProtection;use NextPDF\Cloudflare\ApiProtectionConfig;
$protection = new ApiProtection( config: new ApiProtectionConfig(maxRequestsPerMinute: 30), keyValidator: new ApiKeyValidator([getenv('RENDER_API_KEY') ?: '']),);
$decision = $protection->checkRequest( clientId: $clientIp, payloadSize: strlen($html), apiKey: $presentedApiKey,);
if (!$decision->allowed) { // Reject with 429 and rate-limit headers before any render call. return [429, $decision->toHeaders(), $decision->denialReason];}動作:API キー、ペイロードサイズ、続いてクライアントごとのレート制限を検証し、単一の判定結果と、リクエストが拒否された場合に付与するレスポンスヘッダーを返します。
レンダラー
「レンダラー」という見出しのセクション次の表は、中核となるレンダラー API をまとめたものです。設定の構築、レンダラーの作成、レンダリングや到達性の呼び出しを行うときに使用します。
| シンボル | パラメーター | 既定の動作 | 戻り値 | スローまたは失敗の要因 | 備考 |
|---|---|---|---|---|---|
new CloudflareRendererConfig(string $workerUrl, string $apiToken, int $renderTimeout = 30, string $defaultCss = '', int $maxHtmlSize = 5000000, ?string $r2FontBucket = null, bool $fallbackToLocal = true, array $pinnedPublicKeys = [], array $backupPublicKeys = []) | Worker URL、ベアラートークン、タイムアウト、CSS、サイズ上限、省略可能な R2 フォントバケット、フォールバックフラグ、ピンのセット。 | ローカルフォールバック有効。ピン配列が空の場合はピン留め無効。 | CloudflareRendererConfig | 想定なし。 | API トークンは秘匿。Worker URL は HTTPS を推奨。 |
CloudflareRendererConfig::fromArray(array $config) | worker_url、api_token、render_timeout、default_css、max_html_size、r2_font_bucket、fallback_to_local、ピン配列。 | 省略可能なキーが未指定の場合は、コンストラクターの既定値。 | CloudflareRendererConfig | 想定なし。 | フレームワーク形式の設定配列に対応。 |
CloudflareRendererConfig::isValid() | なし。 | 空でない Worker URL と API トークンが必要。 | bool | 想定なし。 | 設定が無効な場合、レンダラーでフォールバックまたは失敗が発生。 |
CloudflareRendererConfig::allPublicKeyPins() | なし。 | プライマリとバックアップの公開鍵ピンを結合。 | list<string> | 想定なし。 | リストが空の場合、ピン留めは無効。 |
new CloudflareHtmlRenderer(CloudflareRendererConfig $config, ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, ?LoggerInterface $logger = null, ?LocalRendererFactoryInterface $localRendererFactory = null, ?HtmlSecurityPolicyInterface $htmlSecurityPolicy = null, ?ResponseFactoryInterface $responseFactory = null) | 設定、PSR HTTP 依存関係、省略可能なロガー、ローカルフォールバックファクトリー、HTML ポリシー、レスポンスファクトリー。 | 既定では DefaultHtmlSecurityPolicy(HTML ポリシー未指定時)。 | CloudflareHtmlRenderer | コンテナーの結線エラー。 | レスポンスファクトリーにより、必要に応じてピン留めされた cURL トランスポートを有効化。 |
CloudflareHtmlRenderer::render(string $html, float $widthPt = 595.28, float $heightPt = 0, array $fontFiles = []) | HTML、ページ幅、ページ高さ、R2 内のフォントファイル。 | A4 幅、高さ自動、フォントファイルなし。 | CloudflareRenderResult | CloudflareNotAvailableException、CloudflareRenderException、検証失敗。 | ネットワーク I/O の前に HTML サイズと Worker URL を検証。 |
CloudflareHtmlRenderer::getHtmlSecurityPolicy() | なし。 | 構成済みのパースレイヤーポリシー。 | HtmlSecurityPolicyInterface | 想定なし。 | エンドポイント保護や Worker URL 検証との併用。 |
CloudflareHtmlRenderer::isAvailable() | なし。 | 設定が有効な場合、Worker に HEAD リクエストを送信。 | bool | エラー時は false。 | 準備状態の確認用。唯一の実行時ガードとしては不適切。 |
レンダラーの値オブジェクトとセキュリティ
「レンダラーの値オブジェクトとセキュリティ」という見出しのセクションrequest/result の値オブジェクト(CloudflareRenderResult、CloudflareRenderPayload)や、ネットワーク I/O より前に HTML・Worker URL・DNS ピンを検証する静的なトランスポートレイヤーのチェックを扱うときに、この表を使用します。
| シンボル | パラメーター | 既定の動作 | 戻り値 | スローまたは失敗の要因 | 備考 |
|---|---|---|---|---|---|
new CloudflareRenderResult(string $pdfData, float $widthPt, float $heightPt, float $contentHeightPx = 0.0, string $renderLocation = '', float $renderTimeMs = 0.0) | PDF バイト列、幅、高さ、計測されたコンテンツ高さ、エッジロケーション、レンダリング時間。 | Worker が報告しない場合、メタデータは空。 | CloudflareRenderResult | 想定なし。 | 通常は CloudflareResponseParser::parse() により返却。 |
CloudflareRenderResult::isValid() | なし。 | PDF ヘッダーで始まる、空でない PDF バイト列かどうかの確認。 | bool | 想定なし。 | アーカイブ前、またはバイト列を別のレイヤーへ渡す前に使用。 |
CloudflareRenderResult::size() | なし。 | レンダリング済み PDF のバイト数。 | int | 想定なし。 | クォータや監査ロジックへの入力。 |
new CloudflareRenderPayload(string $html, float $widthPt, float $heightPt = 0, string $defaultCss = '', ?string $r2FontBucket = null, array $fontFiles = []) | HTML、サイズ、CSS、省略可能な R2 フォントバケット、フォントファイルのリスト。 | 高さ自動、既定 CSS なし、R2 フォントバケットなし、フォントファイルなし。 | CloudflareRenderPayload | 想定なし。 | リクエストペイロードの値オブジェクト。 |
CloudflareRenderPayload::toJson() | なし。 | Worker 向けの HTML、サイズ、CSS、フォント参照のシリアライズ。 | string | JSON エンコードエラー。 | 低レベルのリクエストペイロード API。 |
CloudflareResponseParser::parse(ResponseInterface $response, float $requestedWidthPt) | Worker のレスポンスと要求された幅。 | バイナリ PDF レスポンスと構造化 JSON レスポンスの両方を受け付け。 | CloudflareRenderResult | 失敗または無効な Worker 出力に対する CloudflareRenderException。 | レンダラーが使用する中心的なパーサー。 |
CloudflareSecurityPolicy::validate(string $html, int $maxSize) | HTML 入力とサイズ上限。 | パッケージの HTML 入力ポリシーを適用。 | void | 検証例外。 | 信頼できない入力のチェックは、Worker の境界の外側で実行。 |
CloudflareSecurityPolicy::validateWorkerUrl(string $url) | Worker の URL。 | 宛先のパースと検証。 | array | 検証例外。 | ネットワーク I/O の前に、安全でないエンドポイント形式をブロック。 |
CloudflareSecurityPolicy::assertPinsStillValid(string $host, array $pinnedIps) | ホストとピン留めされた IP リスト。 | DNS ピンの期待値を検証。 | void | ピンが古い、または無効な場合の検証例外。 | ピン留めされたデプロイの運用チェック時に使用。 |
API 保護
「API 保護」という見出しのセクションレンダリングエンドポイントを保護するときに、この表を使用します。API キーの検証、ペイロードサイズとレート制限のチェック、およびそれらが生成する result/header オブジェクトを扱います。
| シンボル | パラメーター | 既定の動作 | 戻り値 | スローまたは失敗の要因 | 備考 |
|---|---|---|---|---|---|
new ApiProtection(ApiProtectionConfig $config, ?ApiKeyValidator $keyValidator = null, ?Closure $clock = null) | 保護設定、省略可能なキーバリデーター、省略可能なクロック。 | クロック未指定時はシステム時刻。 | ApiProtection | 想定なし。 | テストでは決定論的なクロックを注入。 |
ApiProtection::checkRequest(string $clientId, int $payloadSize, string $apiKey = '') | クライアント識別子、ペイロードサイズ、省略可能な API キー。 | API キー空欄が許可されるのは、設定でキーが必須でない場合のみ。 | ApiProtectionResult | 想定なし。 | API キー、サイズ、続いてレート制限の確認。 |
ApiProtection::getRateLimit(string $clientId) | クライアント識別子。 | リクエストの記録なし。 | RateLimitResult | 想定なし。 | レート制限ヘッダーの追加に使用。 |
new ApiKeyValidator(array $validKeys = []) | 有効なキーの平文リスト。 | リストが空の場合、すべてのキーを拒否。 | ApiKeyValidator | 想定なし。 | シークレットはコード外に保存し、設定経由で読み込み。 |
ApiKeyValidator::validate(string $key) | 生のキー。 | 構成済み平文キーとのタイミングセーフな比較。 | bool | 想定なし。 | 機密パラメーター。生のキーはログに記録しないこと。 |
ApiKeyValidator::addKey(string $key) | 生のキー。 | ハッシュ化したキーを新しいバリデーターインスタンスに追加。 | self | 想定なし。 | 返されたインスタンスを更新後のバリデーターとして扱うこと。 |
ApiKeyValidator::revokeKey(string $key) | 生のキー。 | 一致するハッシュを新しいバリデーターインスタンスから削除。 | self | 想定なし。 | 返されたインスタンスを更新後のバリデーターとして扱うこと。 |
ApiKeyValidator::hashKey(string $key) | 生のキー。 | 保存用ハッシュ表現の生成。 | string | 想定なし。 | ハッシュをログやクライアントへのレスポンスに公開しないこと。 |
ApiKeyValidator::validateHashed(string $key, array $hashedKeys) | 生のキーと候補ハッシュ。 | 指定されたハッシュとの定数時間比較。 | bool | 想定なし。 | カスタムキーストア向けの低レベルヘルパー。 |
new ApiProtectionConfig(int $maxRequestsPerMinute = 60, int $maxRequestsPerHour = 1000, int $maxPayloadSizeBytes = 10485760, array $allowedOrigins = [], bool $requireApiKey = true, string $apiKeyHeader = 'X-Api-Key', int $rateLimitWindowSeconds = 60) | リクエスト上限、ペイロード上限、許可するオリジン、API キーの必須要件、ヘッダー名、ウィンドウ長。 | 60/minute、1000/hour、ペイロード 10 MiB、API キー必須。 | ApiProtectionConfig | 想定なし。 | テストでは直接構築、または fromArray() で読み込み。 |
ApiProtectionConfig::fromArray(array $data) | max_requests_per_minute、max_requests_per_hour、max_payload_size_bytes、allowed_origins、require_api_key、api_key_header、rate_limit_window_seconds。 | キーが未指定の場合は、コンストラクターの既定値。 | ApiProtectionConfig | 想定なし。 | フレームワーク設定の読み込みに使用。 |
ApiProtectionConfig::isValid() | なし。 | 正の上限値と整合した size/window 値が必要。 | bool | 想定なし。 | エンドポイント公開前の検証。 |
new ApiProtectionResult(bool $allowed, string $denialReason = '', ?RateLimitResult $rateLimit = null) | 判定結果、拒否理由、省略可能なレート制限結果。 | 拒否理由は空、レート制限結果はなし。 | ApiProtectionResult | 想定なし。 | ApiProtection::checkRequest() が返すオブジェクト。 |
ApiProtectionResult::toHeaders() | なし。 | レートデータが存在する場合、レート制限ヘッダーを出力。 | array<string, string> | 想定なし。 | Worker またはフレームワークのレスポンスに付与。 |
new RateLimitResult(bool $allowed, int $remainingRequests, int $retryAfterSeconds, string $clientId) | 判定結果、残り回数、リトライ遅延、クライアント ID。 | 既定値なし。 | RateLimitResult | 想定なし。 | 1 回のチェックに対する不変の結果。 |
RateLimitResult::toHeaders() | なし。 | 残り上限とリセットのヘッダーを出力。 | array<string, string> | 想定なし。 | 可観測性とクライアントのバックオフに使用。 |
new RateLimitEntry(string $clientId, int $requestCount = 0, int $windowStart = 0, int $hourlyCount = 0, int $hourlyWindowStart = 0) | クライアント ID と可変のカウンター。 | カウンターはゼロから開始。 | RateLimitEntry | 想定なし。 | インメモリの追跡オブジェクト。 |
RateLimitEntry::increment() | なし。 | インメモリカウンターをインクリメント。対象は 1 つの client/window。 | void | 想定なし。 | 低レベルヘルパー。ApiProtection が使用。 |
RateLimitEntry::isExpired(int $windowSeconds) | ウィンドウ長(秒)。 | 現在時刻との比較。 | bool | 想定なし。 | 実行時の有効期限ヘルパー。 |
RateLimitEntry::isExpiredAt(int $now, int $windowSeconds) | クロック値とウィンドウ長。 | 指定されたクロック値との比較。 | bool | 想定なし。 | 決定論的なテストヘルパー。 |
RateLimitEntry::reset() | なし。 | カウントとウィンドウ開始時刻のリセット。 | void | 想定なし。 | 新しいウィンドウ開始時に使用。 |
R2 アーカイブ
「R2 アーカイブ」という見出しのセクションレンダリング済み PDF を Cloudflare R2 に保存するときに、この表を使用します。アーカイブサービス、設定、オブジェクトキー型、および URL を公開する前に確認するアップロード結果を扱います。
| シンボル | パラメーター | 既定の動作 | 戻り値 | スローまたは失敗の要因 | 備考 |
|---|---|---|---|---|---|
new R2ArchiveManager(R2ArchiveConfig $config, ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory) | R2 設定と PSR HTTP の factories/client。 | 構築時のネットワーク呼び出しなし。 | R2ArchiveManager | コンテナーの結線エラー。 | 中心となるアーカイブサービス。 |
R2ArchiveManager::upload(string $pdfData, string $filename, array $metadata = []) | 生の PDF バイト列、元のファイル名、文字列メタデータ。 | メタデータは空、キーは日付でパーティション分割。 | R2UploadResult | 設定、サイズ、HTTP、またはトランスポート失敗時には、失敗を示す結果。 | 通常のアップロード失敗ではスローなし。 |
R2ArchiveManager::generateSignedUrl(string $key, int $expiresInSeconds = 3600) | オブジェクトキーと URL の TTL。 | 1 時間有効な署名付き URL。 | string | 無効な設定による署名エラー。 | 機密 PDF では TTL を短く維持。 |
R2ArchiveManager::buildObjectKey(string $filename) | 元のファイル名。 | 構成済みパスプレフィックスと現在の日付を使用。 | R2ObjectKey | 想定なし。 | 予測可能なアーカイブのパーティション分割に使用。 |
R2ArchiveManager::createPutRequest(R2ObjectKey $key, string $data, array $metadata = []) | オブジェクトキー、生のバイト列、メタデータ。 | PUT リクエストに署名。 | RequestInterface | リクエスト構築エラー。 | カスタムトランスポート向けの低レベル API。 |
new R2ArchiveConfig(string $bucketName, string $accountId, string $accessKeyId, string $secretAccessKey, string $endpoint = '', string $pathPrefix = 'pdfs/', int $maxFileSizeBytes = 104857600) | バケット、アカウント ID、認証情報、エンドポイントの上書き、キープレフィックス、最大オブジェクトサイズ。 | 導出エンドポイント、pdfs/ プレフィックス、最大オブジェクトサイズ 100 MiB。 | R2ArchiveConfig | 無効なバケット名に対する InvalidArgumentException。 | 認証情報はシークレットを含む設定として扱うこと。 |
R2ArchiveConfig::fromArray(array $data) | アカウント ID、バケット、認証情報、パスプレフィックス、エンドポイントの上書き、最大サイズ。 | 値が未指定の場合は、コンストラクターの既定値。 | R2ArchiveConfig | 指定された場合の無効なバケット名。 | アプリケーション設定の読み込みに使用。 |
R2ArchiveConfig::isValid() | なし。 | 空でないアカウント、バケット、アクセスキー、シークレットキーが必要。 | bool | 想定なし。 | 設定が無効な場合、アップロードは構造化された結果とともに失敗。 |
R2ArchiveConfig::getEndpoint() | なし。 | 明示的エンドポイントを使用、またはアカウント ID から Cloudflare R2 エンドポイントを導出。 | string | 想定なし。 | 署名付きリクエストの構築に使用。 |
new R2ObjectKey(string $key, string $bucket) | 完全なオブジェクトキーとバケット。 | 正規化なし。 | R2ObjectKey | 想定なし。 | 通常は R2ObjectKey::generate() により作成。 |
R2ObjectKey::generate(string $prefix, string $filename, ?DateTimeInterface $date = null) | プレフィックス、元のファイル名、省略可能な日付。 | 日付でパーティション分割され、サニタイズされたオブジェクトキー。 | R2ObjectKey | 想定なし。 | 決定論的なキーを得るため、テストでは日付を注入。 |
R2ObjectKey::fullPath() | なし。 | パーティションパスとオブジェクトファイル名の結合。 | string | 想定なし。 | この値をオブジェクトキーとして保存。 |
new R2UploadResult(bool $success, string $key, string $etag = '', int $size = 0, string $error = '') | 成功フラグ、オブジェクトキー、ETag、バイトサイズ、エラーメッセージ。 | ETag は空、サイズはゼロ、エラーは空。 | R2UploadResult | 想定なし。 | R2ArchiveManager::upload() が返すオブジェクト。 |
R2UploadResult::isValid() | なし。 | アップロード成功、かつキーと ETag の両方が存在する場合に有効。 | bool | 想定なし。 | URL 公開前に確認。 |
R2UploadResult::publicUrl(string $customDomain = '') | 省略可能なカスタム公開ドメイン。 | カスタムドメイン未指定時は、オブジェクトキーをそのまま返却。 | string | 想定なし。 | 機密ドキュメントでは、ポリシーで許可されていない限り公開 URL を避けること。 |
トランスポートヘルパー
「トランスポートヘルパー」という見出しのセクション低レベルの結線にのみ、この表を使用します。cURL レベルの IP/SPKI ピン留めと、Worker に到達できないときのフォールバック経路として使われるローカルレンダラーのコントラクトを扱います。
| シンボル | パラメーター | 既定の動作 | 戻り値 | スローまたは失敗の要因 | 備考 |
|---|---|---|---|---|---|
new PinnedCurlTransport(ResponseFactoryInterface $responseFactory, StreamFactoryInterface $streamFactory, array $pinnedIps = [], array $pinnedPublicKeys = [], int $timeoutSeconds = 30) | PSR-17 ファクトリー、ピン留めされた IP、ピン留めされた公開鍵、タイムアウト。 | ピンなし、タイムアウト 30 秒。 | PinnedCurlTransport | 想定なし。 | cURL レベルのピン留めが必要な場合のみ使用。 |
PinnedCurlTransport::sendRequest(RequestInterface $request) | PSR-7 リクエスト。 | 構成済みタイムアウトとピン留め制御により、cURL 経由で送信。 | ResponseInterface | PSR-18 のトランスポート例外。 | フレームワークの HTTP クライアントで同じピン留めポリシーを強制できない場合のみ使用。 |
PinnedCurlTransport::buildCurlOptions(RequestInterface $request, string $host, int $port) | リクエスト、ターゲットホスト、ターゲットポート。 | 次に sendRequest() が使用する cURL オプション配列を構築。 | array | 無効なリクエスト、またはピン設定エラー。 | 低レベルのテストおよび診断用フック。 |
LocalRendererInterface::render(string $html, array $options = []) | HTML とレンダラーのオプション。 | コントラクトのみ。既定値は実装側で決定。 | string | 実装固有のレンダリングエラー。 | Worker レンダリングが利用できないときのローカルフォールバックとして使用。 |
LocalRendererFactoryInterface::create() | なし。 | ローカルレンダラー実装を作成。 | LocalRendererInterface | ファクトリーまたは依存関係のエラー。 | フォールバックレンダラーの構築を CloudflareHtmlRenderer の外に保持。 |
開発上の注意
「開発上の注意」という見出しのセクション- Worker URL をネットワークの境界として扱ってください。レンダリング前に、宛先、サイズ、認証を検証してください。
- API 保護の結果は、例外による制御フローではなく、ポリシーの出力として使用してください。
- R2 アップロードは、構造化された成功またはエラーの結果を返します。両方の経路を処理してください。