Aller au contenu

Référence de l'API Cloudflare

Le package NextPDF\Cloudflare sert de pont de rendu en périphérie : ton processus PHP garde le HTML, tandis qu’un Worker Cloudflare héberge le navigateur headless. Le package expose un renderer HTML adossé au Worker (CloudflareHtmlRenderer) et les value objects qu’il renvoie, une couche de protection des requêtes destinée aux endpoints de rendu (ApiProtection), un service d’archivage R2 pour stocker les PDF rendus (R2ArchiveManager), ainsi que des helpers de transport épinglé pour le durcissement TLS/DNS. La configuration est portée par trois objets immuables (CloudflareRendererConfig, ApiProtectionConfig, R2ArchiveConfig).

Pour commencer : si tu découvres le package, construis un CloudflareRendererConfig, branche-le dans CloudflareHtmlRenderer, puis appelle render(). Ce seul appel envoie ton HTML au Worker et te renvoie un CloudflareRenderResult contenant les octets du PDF. Tout le reste (protection, archivage, épinglage) s’articule autour de ce même appel.

Les extraits ci-dessous couvrent les workflows réels les plus fréquents de ce package. Chacun est autonome, vérifié dans le code source de src/Cloudflare/, et lit les secrets depuis l’environnement.

Rendre une chaîne HTML en PDF en périphérie — l’appel de rendu canonique unique :

<?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);
}

Ce qu’il fait : il transmet le HTML au Worker via HTTPS et écrit sur le disque les octets du PDF A4 renvoyé, une fois que isValid() a confirmé qu’il s’agit bien d’un PDF.

Archiver un PDF rendu dans R2 et renvoyer un lien à courte durée de vie :

<?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;

Ce qu’il fait : il téléverse les octets du PDF vers une clé R2 partitionnée par date et, en cas de succès, génère une URL pré-signée de 10 minutes pour un téléchargement temporaire.

Protéger un endpoint de rendu avant de déclencher un travail Worker coûteux :

<?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];
}

Ce qu’il fait : il valide la clé d’API, contrôle la taille de la charge utile, puis la limite de débit par client, et renvoie une décision unique avec les en-têtes de réponse à attacher quand la requête est refusée.

Le tableau du renderer constitue la surface d’API centrale. Utilise-le quand tu construis la configuration, que tu bâtis le renderer ou que tu effectues les appels de rendu et de disponibilité.

SymboleParamètresComportement par défautRenvoieLève ou échoue avecNotes
new CloudflareRendererConfig(string $workerUrl, string $apiToken, int $renderTimeout = 30, string $defaultCss = '', int $maxHtmlSize = 5000000, ?string $r2FontBucket = null, bool $fallbackToLocal = true, array $pinnedPublicKeys = [], array $backupPublicKeys = [])URL du Worker, jeton bearer, délai d’expiration, CSS, limite de taille, bucket de polices R2 optionnel, drapeau de repli, ensembles d’épingles.Le repli local est activé ; l’épinglage est désactivé quand les tableaux d’épingles sont vides.CloudflareRendererConfigaucune attendue.Garde le jeton d’API secret ; préfère les URL de Worker en HTTPS.
CloudflareRendererConfig::fromArray(array $config)worker_url, api_token, render_timeout, default_css, max_html_size, r2_font_bucket, fallback_to_local, tableaux d’épingles.Les clés optionnelles manquantes utilisent les valeurs par défaut du constructeur.CloudflareRendererConfigaucune attendue.Correspond aux tableaux de configuration de style framework.
CloudflareRendererConfig::isValid()aucun.Exige une URL de Worker et un jeton d’API non vides.boolaucune attendue.Une configuration invalide déclenche un repli ou un échec dans le renderer.
CloudflareRendererConfig::allPublicKeyPins()aucun.Combine les épingles de clé publique primaires et de secours.list<string>aucune attendue.Une liste vide désactive l’épinglage.
new CloudflareHtmlRenderer(CloudflareRendererConfig $config, ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, ?LoggerInterface $logger = null, ?LocalRendererFactoryInterface $localRendererFactory = null, ?HtmlSecurityPolicyInterface $htmlSecurityPolicy = null, ?ResponseFactoryInterface $responseFactory = null)Configuration, dépendances HTTP PSR, logger optionnel, factory de repli local optionnelle, politique HTML optionnelle, factory de réponse optionnelle.Utilise DefaultHtmlSecurityPolicy quand aucune politique HTML n’est fournie.CloudflareHtmlRendererErreurs de câblage du conteneur.La factory de réponse active le transport cURL épinglé lorsque c’est nécessaire.
CloudflareHtmlRenderer::render(string $html, float $widthPt = 595.28, float $heightPt = 0, array $fontFiles = [])HTML, largeur de page, hauteur de page, fichiers de polices dans R2.Largeur A4 ; hauteur automatique ; aucun fichier de police.CloudflareRenderResultCloudflareNotAvailableException, CloudflareRenderException, échecs de validation.Valide la taille du HTML et l’URL du Worker avant toute E/S réseau.
CloudflareHtmlRenderer::getHtmlSecurityPolicy()aucun.Renvoie la politique de la couche de parsing configurée.HtmlSecurityPolicyInterfaceaucune attendue.À utiliser avec la protection des endpoints et la validation de l’URL du Worker.
CloudflareHtmlRenderer::isAvailable()aucun.Requête HEAD vers le Worker quand la configuration est valide.boolRenvoie false en cas d’erreur.À utiliser pour les vérifications de disponibilité, pas comme unique garde-fou à l’exécution.

Utilise ce tableau quand tu as besoin des value objects de request/result (CloudflareRenderResult, CloudflareRenderPayload) ou des vérifications statiques de la couche de transport qui valident le HTML, l’URL du Worker et les épingles DNS avant toute E/S réseau.

SymboleParamètresComportement par défautRenvoieLève ou échoue avecNotes
new CloudflareRenderResult(string $pdfData, float $widthPt, float $heightPt, float $contentHeightPx = 0.0, string $renderLocation = '', float $renderTimeMs = 0.0)Octets du PDF, largeur, hauteur, hauteur de contenu mesurée, emplacement en périphérie, durée de rendu.Métadonnées vides quand le Worker ne les rapporte pas.CloudflareRenderResultaucune attendue.Généralement renvoyé par CloudflareResponseParser::parse().
CloudflareRenderResult::isValid()aucun.Vérifie la présence d’octets PDF non vides commençant par un en-tête PDF.boolaucune attendue.À utiliser avant l’archivage ou la transmission des octets à une autre couche.
CloudflareRenderResult::size()aucun.Compte les octets du PDF rendu.intaucune attendue.Alimente la logique de quota et d’audit avec cette valeur.
new CloudflareRenderPayload(string $html, float $widthPt, float $heightPt = 0, string $defaultCss = '', ?string $r2FontBucket = null, array $fontFiles = [])HTML, dimensions, CSS, bucket de polices R2 optionnel, liste de fichiers de polices.Hauteur automatique, pas de CSS par défaut, pas de bucket de polices R2, pas de fichiers de polices.CloudflareRenderPayloadaucune attendue.Value object de la charge utile de requête.
CloudflareRenderPayload::toJson()aucun.Sérialise le HTML, la taille, le CSS et les références de polices pour le Worker.stringErreurs d’encodage JSON.API bas niveau de la charge utile de requête.
CloudflareResponseParser::parse(ResponseInterface $response, float $requestedWidthPt)Réponse du Worker et largeur demandée.Accepte les réponses PDF binaires et les réponses JSON structurées.CloudflareRenderResultCloudflareRenderException en cas de sortie du Worker en échec ou invalide.Parser central utilisé par le renderer.
CloudflareSecurityPolicy::validate(string $html, int $maxSize)Entrée HTML et limite de taille.Applique la politique d’entrée HTML du package.voidException de validation.Maintient les contrôles d’entrée non fiable en dehors de la frontière du Worker.
CloudflareSecurityPolicy::validateWorkerUrl(string $url)URL du Worker.Analyse et valide la destination.arrayException de validation.Bloque les formes d’endpoint non sûres avant toute E/S réseau.
CloudflareSecurityPolicy::assertPinsStillValid(string $host, array $pinnedIps)Hôte et liste d’IP épinglées.Vérifie les attentes d’épingles DNS.voidException de validation quand les épingles sont périmées ou invalides.À utiliser lors des vérifications opérationnelles pour les déploiements épinglés.

Utilise ce tableau quand tu protèges un endpoint de rendu : validation de la clé d’API, contrôles de la taille de la charge utile et de la limite de débit, et les objets result/header qu’ils produisent.

SymboleParamètresComportement par défautRenvoieLève ou échoue avecNotes
new ApiProtection(ApiProtectionConfig $config, ?ApiKeyValidator $keyValidator = null, ?Closure $clock = null)Configuration de protection, validateur de clé optionnel, horloge optionnelle.Utilise l’heure système quand aucune horloge n’est fournie.ApiProtectionaucune attendue.Injecte une horloge déterministe dans les tests.
ApiProtection::checkRequest(string $clientId, int $payloadSize, string $apiKey = '')Identifiant du client, taille de la charge utile, clé d’API optionnelle.Une clé d’API vide n’est autorisée que lorsque la configuration n’exige pas de clés.ApiProtectionResultaucune attendue.Vérifie la clé d’API, la taille, puis les limites de débit.
ApiProtection::getRateLimit(string $clientId)Identifiant du client.N’enregistre pas de requête.RateLimitResultaucune attendue.À utiliser pour ajouter des en-têtes de limite de débit.
new ApiKeyValidator(array $validKeys = [])Liste de clés valides en clair.Une liste vide rejette toutes les clés.ApiKeyValidatoraucune attendue.Stocke les secrets en dehors du code et hydrate-les via la configuration.
ApiKeyValidator::validate(string $key)Clé brute.Comparaison à temps constant avec les clés en clair configurées.boolaucune attendue.Paramètre sensible ; ne journalise pas les clés brutes.
ApiKeyValidator::addKey(string $key)Clé brute.Ajoute une clé hachée à une nouvelle instance de validateur.selfaucune attendue.Traite l’instance renvoyée comme le validateur mis à jour.
ApiKeyValidator::revokeKey(string $key)Clé brute.Supprime le hachage correspondant d’une nouvelle instance de validateur.selfaucune attendue.Traite l’instance renvoyée comme le validateur mis à jour.
ApiKeyValidator::hashKey(string $key)Clé brute.Produit la représentation de hachage stockée.stringaucune attendue.N’expose pas les hachages dans les journaux ni dans les réponses client.
ApiKeyValidator::validateHashed(string $key, array $hashedKeys)Clé brute et hachages candidats.Comparaison à temps constant avec les hachages fournis.boolaucune attendue.Helper bas niveau pour les stores de clés personnalisés.
new ApiProtectionConfig(int $maxRequestsPerMinute = 60, int $maxRequestsPerHour = 1000, int $maxPayloadSizeBytes = 10485760, array $allowedOrigins = [], bool $requireApiKey = true, string $apiKeyHeader = 'X-Api-Key', int $rateLimitWindowSeconds = 60)Limites de requêtes, limite de charge utile, origines autorisées, exigence de clé d’API, nom d’en-tête, durée de la fenêtre.60/minute, 1000/hour, charge utile de 10 Mio, clé d’API requise.ApiProtectionConfigaucune attendue.Construis-le directement dans les tests ou hydrate-le avec 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.Les clés manquantes utilisent les valeurs par défaut du constructeur.ApiProtectionConfigaucune attendue.À utiliser pour l’hydratation de la configuration d’un framework.
ApiProtectionConfig::isValid()aucun.Exige des limites positives et des valeurs size/window cohérentes.boolaucune attendue.Valide la configuration avant d’exposer un endpoint.
new ApiProtectionResult(bool $allowed, string $denialReason = '', ?RateLimitResult $rateLimit = null)Décision, motif de refus, résultat de limite de débit optionnel.Motif de refus vide et aucun résultat de limite de débit.ApiProtectionResultaucune attendue.Renvoyé par ApiProtection::checkRequest().
ApiProtectionResult::toHeaders()aucun.Émet les en-têtes de limite de débit quand des données de débit existent.array<string, string>aucune attendue.À attacher aux réponses du Worker ou du framework.
new RateLimitResult(bool $allowed, int $remainingRequests, int $retryAfterSeconds, string $clientId)Décision, nombre restant, délai de réessai, ID du client.Aucune valeur par défaut.RateLimitResultaucune attendue.Résultat immuable pour une seule vérification.
RateLimitResult::toHeaders()aucun.Émet les en-têtes de limite restante et de réinitialisation.array<string, string>aucune attendue.À utiliser pour l’observabilité et le backoff client.
new RateLimitEntry(string $clientId, int $requestCount = 0, int $windowStart = 0, int $hourlyCount = 0, int $hourlyWindowStart = 0)ID du client et compteurs mutables.Les compteurs démarrent à zéro.RateLimitEntryaucune attendue.Objet de suivi en mémoire.
RateLimitEntry::increment()aucun.Incrémente le compteur en mémoire pour un seul client/window.voidaucune attendue.Helper bas niveau utilisé par ApiProtection.
RateLimitEntry::isExpired(int $windowSeconds)Durée de la fenêtre en secondes.Compare avec l’heure actuelle.boolaucune attendue.Helper d’expiration à l’exécution.
RateLimitEntry::isExpiredAt(int $now, int $windowSeconds)Valeur d’horloge et durée de la fenêtre.Compare avec la valeur d’horloge fournie.boolaucune attendue.Helper de test déterministe.
RateLimitEntry::reset()aucun.Réinitialise le compteur et l’heure de début de la fenêtre.voidaucune attendue.Utilisé quand une nouvelle fenêtre commence.

Utilise ce tableau quand tu stockes des PDF rendus dans Cloudflare R2 : le service d’archivage, ses types de configuration et de clé d’objet, et le résultat de téléversement que tu inspectes avant d’exposer une URL.

SymboleParamètresComportement par défautRenvoieLève ou échoue avecNotes
new R2ArchiveManager(R2ArchiveConfig $config, ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory)Configuration R2 et factories/client HTTP PSR.Aucun appel réseau pendant la construction.R2ArchiveManagerErreurs de câblage du conteneur.Service d’archivage principal.
R2ArchiveManager::upload(string $pdfData, string $filename, array $metadata = [])Octets PDF bruts, nom de fichier d’origine, métadonnées de type chaîne.Métadonnées vides ; clé partitionnée par date.R2UploadResultRenvoie un résultat d’échec en cas d’échec de configuration, de taille, HTTP ou de transport.Ne lève pas d’exception pour un échec de téléversement normal.
R2ArchiveManager::generateSignedUrl(string $key, int $expiresInSeconds = 3600)Clé d’objet et TTL de l’URL.URL signée d’une heure.stringErreurs de signature dues à une configuration invalide.Conserve des TTL courts pour les PDF sensibles.
R2ArchiveManager::buildObjectKey(string $filename)Nom de fichier d’origine.Utilise le préfixe de chemin configuré et la date actuelle.R2ObjectKeyaucune attendue.À utiliser pour un partitionnement d’archive prévisible.
R2ArchiveManager::createPutRequest(R2ObjectKey $key, string $data, array $metadata = [])Clé d’objet, octets bruts, métadonnées.Signe une requête PUT.RequestInterfaceErreurs de construction de requête.API bas niveau pour les transports personnalisés.
new R2ArchiveConfig(string $bucketName, string $accountId, string $accessKeyId, string $secretAccessKey, string $endpoint = '', string $pathPrefix = 'pdfs/', int $maxFileSizeBytes = 104857600)Bucket, ID de compte, identifiants, surcharge d’endpoint, préfixe de clé, taille d’objet maximale.Endpoint dérivé, préfixe pdfs/, taille d’objet maximale de 100 Mio.R2ArchiveConfigInvalidArgumentException pour les noms de bucket invalides.Traite les identifiants comme une configuration contenant des secrets.
R2ArchiveConfig::fromArray(array $data)ID de compte, bucket, identifiants, préfixe de chemin, surcharge d’endpoint, taille maximale.Les valeurs manquantes utilisent les valeurs par défaut du constructeur.R2ArchiveConfigNom de bucket invalide s’il est fourni.À utiliser pour l’hydratation de la configuration de l’application.
R2ArchiveConfig::isValid()aucun.Exige un compte, un bucket, une clé d’accès et une clé secrète non vides.boolaucune attendue.Une configuration invalide fait échouer les téléversements avec des résultats structurés.
R2ArchiveConfig::getEndpoint()aucun.Utilise l’endpoint explicite ou dérive l’endpoint Cloudflare R2 à partir de l’ID de compte.stringaucune attendue.Utilisé pour la construction des requêtes signées.
new R2ObjectKey(string $key, string $bucket)Clé d’objet complète et bucket.Aucune normalisation.R2ObjectKeyaucune attendue.Généralement créé par R2ObjectKey::generate().
R2ObjectKey::generate(string $prefix, string $filename, ?DateTimeInterface $date = null)Préfixe, nom de fichier d’origine, date optionnelle.Clé d’objet partitionnée par date et assainie.R2ObjectKeyaucune attendue.Injecte la date dans les tests pour des clés déterministes.
R2ObjectKey::fullPath()aucun.Assemble le chemin de partition et le nom de fichier de l’objet.stringaucune attendue.Stocke cette valeur comme clé d’objet.
new R2UploadResult(bool $success, string $key, string $etag = '', int $size = 0, string $error = '')Indicateur de succès, clé d’objet, ETag, taille en octets, message d’erreur.ETag vide, taille nulle, erreur vide.R2UploadResultaucune attendue.Renvoyé par R2ArchiveManager::upload().
R2UploadResult::isValid()aucun.Valide quand le téléversement a réussi et que la clé et l’ETag sont tous deux présents.boolaucune attendue.Vérifie avant d’exposer des URL.
R2UploadResult::publicUrl(string $customDomain = '')Domaine public personnalisé optionnel.Renvoie la clé d’objet brute quand aucun domaine personnalisé n’est fourni.stringaucune attendue.Évite les URL publiques pour les documents sensibles, sauf si la politique l’autorise.

Utilise ce tableau uniquement pour le câblage bas niveau : l’épinglage IP/SPKI au niveau cURL et les contrats du renderer local utilisés comme chemin de repli quand le Worker est injoignable.

SymboleParamètresComportement par défautRenvoieLève ou échoue avecNotes
new PinnedCurlTransport(ResponseFactoryInterface $responseFactory, StreamFactoryInterface $streamFactory, array $pinnedIps = [], array $pinnedPublicKeys = [], int $timeoutSeconds = 30)Factories PSR-17, IP épinglées, clés publiques épinglées, délai d’expiration.Aucune épingle et délai d’expiration de 30 secondes.PinnedCurlTransportaucune attendue.À utiliser uniquement quand l’épinglage au niveau cURL est requis.
PinnedCurlTransport::sendRequest(RequestInterface $request)Requête PSR-7.Envoie la requête via cURL avec le délai d’expiration et les contrôles d’épinglage configurés.ResponseInterfaceExceptions de transport PSR-18.À utiliser uniquement quand les clients HTTP du framework ne peuvent pas appliquer la même politique d’épinglage.
PinnedCurlTransport::buildCurlOptions(RequestInterface $request, string $host, int $port)Requête, hôte cible, port cible.Construit le tableau d’options cURL utilisé par sendRequest().arrayErreurs de requête ou de configuration d’épingles invalides.Point d’accroche bas niveau pour les tests et le diagnostic.
LocalRendererInterface::render(string $html, array $options = [])HTML et options du renderer.Contrat uniquement ; l’implémentation décide des valeurs par défaut.stringErreurs de rendu propres à l’implémentation.Utilisé comme repli local quand le rendu par le Worker est indisponible.
LocalRendererFactoryInterface::create()aucun.Crée une implémentation de renderer local.LocalRendererInterfaceErreurs de factory ou de dépendance.Maintient la construction du renderer de repli en dehors de CloudflareHtmlRenderer.
  • Considère l’URL du Worker comme une frontière réseau. Valide la destination, la taille et l’authentification avant le rendu.
  • Utilise les résultats de protection de l’API comme des décisions de politique, pas comme un flux de contrôle par exceptions.
  • Les téléversements R2 renvoient des résultats de succès ou d’erreur structurés ; traite les deux cas.