Pular para o conteúdo

Referência da API do Cloudflare

O pacote NextPDF\Cloudflare faz a ponte com a renderização na edge. O processo PHP fica responsável pelo Hypertext Markup Language (HTML), e um Cloudflare Worker executa o navegador headless. O pacote expõe um renderer de HTML apoiado por Worker (CloudflareHtmlRenderer) e os value objects que ele retorna, uma camada de proteção de requisições para endpoints de renderização (ApiProtection), um serviço de arquivamento no R2 para arquivos Portable Document Format (PDF) renderizados (R2ArchiveManager) e auxiliares de transporte com pinning para reforçar Transport Layer Security (TLS) e Domain Name System (DNS). A configuração fica em três objetos imutáveis (CloudflareRendererConfig, ApiProtectionConfig, R2ArchiveConfig).

Para começar, monte um CloudflareRendererConfig, conecte-o ao CloudflareHtmlRenderer e chame render(). Essa chamada envia o HTML ao Worker e retorna um CloudflareRenderResult com os bytes do PDF. Proteção, arquivamento e pinning atuam em torno dessa chamada.

Estes trechos cobrem os fluxos de trabalho que você provavelmente vai usar com mais frequência. Cada um é autossuficiente, foi verificado contra src/Cloudflare/ e lê os segredos a partir do ambiente.

Renderize uma string de HTML para um PDF na edge com a chamada canônica:

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

O que faz: envia o HTML ao Worker por Hypertext Transfer Protocol Secure (HTTPS) e grava em disco os bytes do PDF A4 retornados depois que isValid() confirma que se trata de um PDF real.

Arquive um PDF renderizado no R2 e retorne um link de curta duração:

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

O que faz: envia os bytes do PDF para uma chave do R2 particionada por data e, se a operação for bem-sucedida, cria um uniform resource locator (URL) pré-assinado de 10 minutos para download temporário.

Proteja um endpoint de renderização antes que ele inicie um trabalho caro no 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];
}

O que faz: valida a chave de API e o tamanho do payload, verifica o limite de taxa por cliente e retorna uma decisão junto com os cabeçalhos de resposta a anexar quando a requisição é negada.

Esta tabela cobre a superfície central do renderer. Use-a quando você constrói a configuração, monta o renderer ou faz chamadas de renderização e de verificação de disponibilidade.

SímboloParâmetrosComportamento padrãoRetornoLança ou falha comNotas
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 do Worker, bearer token, timeout, Cascading Style Sheets (CSS), limite de tamanho, bucket de fontes do R2 opcional, flag de fallback, conjuntos de pins.O fallback local fica habilitado; o pinning permanece desligado quando os arrays de pins estão vazios.CloudflareRendererConfigNenhuma esperada.Mantenha o token de API em segredo; prefira URLs de worker em HTTPS.
CloudflareRendererConfig::fromArray(array $config)worker_url, api_token, render_timeout, default_css, max_html_size, r2_font_bucket, fallback_to_local, arrays de pins.Chaves opcionais ausentes usam os valores padrão do construtor.CloudflareRendererConfigNenhuma esperada.Use para arrays de configuração no estilo de framework.
CloudflareRendererConfig::isValid()nenhum.Requer uma URL de worker e um token de API não vazios.boolNenhuma esperada.Uma configuração inválida aciona o fallback ou faz o renderer falhar.
CloudflareRendererConfig::allPublicKeyPins()nenhum.Combina os pins de chave pública primários e de backup.list<string>Nenhuma esperada.Uma lista vazia desativa o pinning.
new CloudflareHtmlRenderer(CloudflareRendererConfig $config, ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, ?LoggerInterface $logger = null, ?LocalRendererFactoryInterface $localRendererFactory = null, ?HtmlSecurityPolicyInterface $htmlSecurityPolicy = null, ?ResponseFactoryInterface $responseFactory = null)Configuração, dependências de Hypertext Transfer Protocol (HTTP) de PHP Standards Recommendation (PSR), logger opcional, factory de fallback local opcional, política de HTML opcional, factory de resposta opcional.Usa DefaultHtmlSecurityPolicy quando nenhuma política de HTML é fornecida.CloudflareHtmlRendererErros de wiring do container.A factory de resposta habilita o transporte cURL com pinning quando necessário.
CloudflareHtmlRenderer::render(string $html, float $widthPt = 595.28, float $heightPt = 0, array $fontFiles = [])HTML, largura da página, altura da página, arquivos de fonte no R2.Largura A4, altura automática, sem arquivos de fonte.CloudflareRenderResultCloudflareNotAvailableException, CloudflareRenderException, falhas de validação.Valida o tamanho do HTML e a URL do worker antes do input/output (I/O) de rede.
CloudflareHtmlRenderer::getHtmlSecurityPolicy()nenhum.Retorna a política configurada da camada de parsing.HtmlSecurityPolicyInterfaceNenhuma esperada.Use em conjunto com a proteção de endpoint e a validação da URL do Worker.
CloudflareHtmlRenderer::isAvailable()nenhum.Envia uma requisição HEAD ao worker quando a configuração é válida.boolRetorna false em caso de erros.Use para verificações de prontidão, não como a única proteção em tempo de execução.

Use esta tabela para os value objects de requisição e de resultado (CloudflareRenderResult, CloudflareRenderPayload) e para as verificações estáticas da camada de transporte que validam o HTML, a URL do Worker e os pins de DNS antes do I/O de rede.

SímboloParâmetrosComportamento padrãoRetornoLança ou falha comNotas
new CloudflareRenderResult(string $pdfData, float $widthPt, float $heightPt, float $contentHeightPx = 0.0, string $renderLocation = '', float $renderTimeMs = 0.0)Bytes do PDF, largura, altura, altura de conteúdo medida, localização na edge, tempo de renderização.Os metadados ficam vazios quando o Worker não os reporta.CloudflareRenderResultNenhuma esperada.Geralmente retornado por CloudflareResponseParser::parse().
CloudflareRenderResult::isValid()nenhum.Verifica se há bytes de PDF não vazios que começam com um cabeçalho de PDF.boolNenhuma esperada.Use antes de arquivar ou passar os bytes para outra camada.
CloudflareRenderResult::size()nenhum.Conta os bytes do PDF renderizado.intNenhuma esperada.Alimente a lógica de cota e de auditoria.
new CloudflareRenderPayload(string $html, float $widthPt, float $heightPt = 0, string $defaultCss = '', ?string $r2FontBucket = null, array $fontFiles = [])HTML, tamanho, CSS, bucket de fontes do R2 opcional, lista de arquivos de fonte.Altura automática, sem CSS padrão, sem bucket de fontes do R2, sem arquivos de fonte.CloudflareRenderPayloadNenhuma esperada.Value object do payload da requisição.
CloudflareRenderPayload::toJson()nenhum.Serializa o HTML, o tamanho, o CSS e as referências de fonte como JavaScript Object Notation (JSON) para o Worker.stringErros de codificação de JSON.API de baixo nível para o payload da requisição.
CloudflareResponseParser::parse(ResponseInterface $response, float $requestedWidthPt)Resposta do Worker e largura solicitada.Aceita respostas de PDF binárias e respostas de JSON estruturadas.CloudflareRenderResultCloudflareRenderException para saída do Worker malsucedida ou inválida.Parser central usado pelo renderer.
CloudflareSecurityPolicy::validate(string $html, int $maxSize)Entrada de HTML e limite de tamanho.Aplica a política de entrada de HTML do pacote.voidExceção de validação.Mantenha as verificações de entrada não confiável fora do limite do Worker.
CloudflareSecurityPolicy::validateWorkerUrl(string $url)URL do Worker.Faz o parsing e valida o destino.arrayExceção de validação.Bloqueia formatos inseguros de endpoint antes do I/O de rede.
CloudflareSecurityPolicy::assertPinsStillValid(string $host, array $pinnedIps)Host e lista de IPs com pin.Verifica os pins de DNS esperados.voidExceção de validação quando os pins estão desatualizados ou inválidos.Use durante as verificações operacionais para implantações com pin.

Use esta tabela quando você protege um endpoint de renderização: validação de chave de API, verificações de tamanho de payload e de limite de taxa, além dos objetos de resultado e de cabeçalho que elas produzem.

SímboloParâmetrosComportamento padrãoRetornoLança ou falha comNotas
new ApiProtection(ApiProtectionConfig $config, ?ApiKeyValidator $keyValidator = null, ?Closure $clock = null)Configuração de proteção, validador de chave opcional, clock opcional.Usa o horário do sistema quando nenhum clock é fornecido.ApiProtectionNenhuma esperada.Injete um clock determinístico nos testes.
ApiProtection::checkRequest(string $clientId, int $payloadSize, string $apiKey = '')Identificador do cliente, tamanho do payload, chave de API opcional.Uma chave de API vazia só é permitida quando a configuração não exige chaves.ApiProtectionResultNenhuma esperada.Verifica a chave de API e o tamanho, depois aplica o limite de taxa.
ApiProtection::getRateLimit(string $clientId)Identificador do cliente.Não registra uma requisição.RateLimitResultNenhuma esperada.Use para adicionar cabeçalhos de limite de taxa.
new ApiKeyValidator(array $validKeys = [])Lista de chaves válidas em texto puro.Uma lista vazia rejeita todas as chaves.ApiKeyValidatorNenhuma esperada.Armazene os segredos fora do código e hidrate-os por meio da configuração.
ApiKeyValidator::validate(string $key)Chave bruta.Compara com as chaves em texto puro configuradas usando lógica resistente a ataques de tempo.boolNenhuma esperada.O parâmetro é sensível; não registre chaves brutas em log.
ApiKeyValidator::addKey(string $key)Chave bruta.Adiciona uma chave com hash a uma nova instância do validador.selfNenhuma esperada.Trate a instância retornada como o validador atualizado.
ApiKeyValidator::revokeKey(string $key)Chave bruta.Remove o hash correspondente de uma nova instância do validador.selfNenhuma esperada.Trate a instância retornada como o validador atualizado.
ApiKeyValidator::hashKey(string $key)Chave bruta.Produz a representação de hash armazenada.stringNenhuma esperada.Não exponha hashes em logs ou em respostas ao cliente.
ApiKeyValidator::validateHashed(string $key, array $hashedKeys)Chave bruta e hashes candidatos.Compara com os hashes fornecidos em tempo constante.boolNenhuma esperada.Auxiliar de baixo nível para armazenamentos de chave personalizados.
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 requisição, limite de payload, origens permitidas, exigência de chave de API, nome do cabeçalho, duração da janela.60/minute, 1000/hour, payload de 10 MiB, chave de API obrigatória.ApiProtectionConfigNenhuma esperada.Construa diretamente nos testes ou hidrate com 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.Chaves ausentes usam os valores padrão do construtor.ApiProtectionConfigNenhuma esperada.Use para hidratar a configuração de framework.
ApiProtectionConfig::isValid()nenhum.Requer limites positivos e valores de tamanho e de janela coerentes.boolNenhuma esperada.Valide antes de expor um endpoint.
new ApiProtectionResult(bool $allowed, string $denialReason = '', ?RateLimitResult $rateLimit = null)Decisão, motivo da negação, resultado de limite de taxa opcional.Motivo de negação vazio e sem resultado de limite de taxa.ApiProtectionResultNenhuma esperada.Retornado por ApiProtection::checkRequest().
ApiProtectionResult::toHeaders()nenhum.Emite cabeçalhos de limite de taxa quando há dados de taxa.array<string, string>Nenhuma esperada.Anexe-os às respostas do Worker ou do framework.
new RateLimitResult(bool $allowed, int $remainingRequests, int $retryAfterSeconds, string $clientId)Decisão, contagem restante, atraso de nova tentativa, identificador do cliente (ID).Sem valores padrão.RateLimitResultNenhuma esperada.Resultado imutável para uma verificação.
RateLimitResult::toHeaders()nenhum.Emite cabeçalhos de limite restante e de reinício.array<string, string>Nenhuma esperada.Use para observabilidade e backoff do cliente.
new RateLimitEntry(string $clientId, int $requestCount = 0, int $windowStart = 0, int $hourlyCount = 0, int $hourlyWindowStart = 0)ID do cliente e contadores mutáveis.Os contadores começam em zero.RateLimitEntryNenhuma esperada.Objeto de rastreamento em memória.
RateLimitEntry::increment()nenhum.Incrementa o contador em memória para um client/window.voidNenhuma esperada.Auxiliar de baixo nível usado por ApiProtection.
RateLimitEntry::isExpired(int $windowSeconds)Duração da janela em segundos.Compara com o horário atual.boolNenhuma esperada.Auxiliar de expiração em tempo de execução.
RateLimitEntry::isExpiredAt(int $now, int $windowSeconds)Valor do clock e duração da janela.Compara com o valor de clock fornecido.boolNenhuma esperada.Auxiliar de teste determinístico.
RateLimitEntry::reset()nenhum.Reinicia a contagem e o horário de início da janela.voidNenhuma esperada.Usado quando uma nova janela começa.

Use esta tabela quando você armazena PDFs renderizados no Cloudflare R2: o serviço de arquivamento, seus tipos de configuração e de object-key, e o resultado de upload que você deve inspecionar antes de expor uma URL.

SímboloParâmetrosComportamento padrãoRetornoLança ou falha comNotas
new R2ArchiveManager(R2ArchiveConfig $config, ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory)Configuração do R2 e factories/client HTTP de PSR.Nenhuma chamada de rede durante a construção.R2ArchiveManagerErros de wiring do container.Serviço de arquivamento principal.
R2ArchiveManager::upload(string $pdfData, string $filename, array $metadata = [])Bytes brutos do PDF, nome de arquivo original, metadados em string.Metadados vazios; chave particionada por data.R2UploadResultRetorna um resultado malsucedido em caso de falha de configuração, de tamanho, de HTTP ou de transporte.Não lança exceção para falhas normais de upload.
R2ArchiveManager::generateSignedUrl(string $key, int $expiresInSeconds = 3600)Chave do objeto e time to live (TTL) da URL.URL assinada de uma hora.stringErros de assinatura decorrentes de configuração inválida.Use TTLs curtos para PDFs sensíveis.
R2ArchiveManager::buildObjectKey(string $filename)Nome de arquivo original.Usa o prefixo de caminho configurado e a data atual.R2ObjectKeyNenhuma esperada.Use para particionamento de arquivamento previsível.
R2ArchiveManager::createPutRequest(R2ObjectKey $key, string $data, array $metadata = [])Chave do objeto, bytes brutos, metadados.Assina uma requisição PUT.RequestInterfaceErros de construção da requisição.API de baixo nível para transportes personalizados.
new R2ArchiveConfig(string $bucketName, string $accountId, string $accessKeyId, string $secretAccessKey, string $endpoint = '', string $pathPrefix = 'pdfs/', int $maxFileSizeBytes = 104857600)Bucket, ID da conta, credenciais, substituição de endpoint, prefixo de chave, tamanho máximo de objeto.Endpoint derivado, prefixo pdfs/, tamanho máximo de objeto de 100 MiB.R2ArchiveConfigInvalidArgumentException para nomes de bucket inválidos.Trate as credenciais como configuração que carrega segredos.
R2ArchiveConfig::fromArray(array $data)ID da conta, bucket, credenciais, prefixo de caminho, substituição de endpoint, tamanho máximo.Valores ausentes usam os valores padrão do construtor.R2ArchiveConfigNome de bucket inválido quando fornecido.Use para hidratar a configuração da aplicação.
R2ArchiveConfig::isValid()nenhum.Requer conta, bucket, chave de acesso e chave secreta não vazios.boolNenhuma esperada.Uma configuração inválida faz os uploads falharem com resultados estruturados.
R2ArchiveConfig::getEndpoint()nenhum.Usa um endpoint explícito ou deriva o endpoint do Cloudflare R2 a partir do ID da conta.stringNenhuma esperada.Usado para construir requisições assinadas.
new R2ObjectKey(string $key, string $bucket)Chave completa do objeto e bucket.Sem normalização.R2ObjectKeyNenhuma esperada.Geralmente criado por R2ObjectKey::generate().
R2ObjectKey::generate(string $prefix, string $filename, ?DateTimeInterface $date = null)Prefixo, nome de arquivo original, data opcional.Chave de objeto particionada por data e sanitizada.R2ObjectKeyNenhuma esperada.Injete a data nos testes para obter chaves determinísticas.
R2ObjectKey::fullPath()nenhum.Junta o caminho da partição e o nome de arquivo do objeto.stringNenhuma esperada.Armazene esse valor como a chave do objeto.
new R2UploadResult(bool $success, string $key, string $etag = '', int $size = 0, string $error = '')Flag de sucesso, chave do objeto, entity tag (ETag), tamanho em bytes, mensagem de erro.ETag vazio, tamanho zero, erro vazio.R2UploadResultNenhuma esperada.Retornado por R2ArchiveManager::upload().
R2UploadResult::isValid()nenhum.Válido quando o upload teve sucesso e tanto a chave quanto o ETag estão presentes.boolNenhuma esperada.Verifique antes de expor URLs.
R2UploadResult::publicUrl(string $customDomain = '')Domínio público personalizado opcional.Retorna a chave do objeto sem formatação quando nenhum domínio personalizado é fornecido.stringNenhuma esperada.Evite URLs públicas para documentos sensíveis, a menos que a política permita.

Use esta tabela apenas para wiring de baixo nível: pinning de Internet Protocol (IP) e de SubjectPublicKeyInfo (SPKI) no nível do cURL, além dos contratos de renderer local usados como caminho de fallback quando o Worker está inacessível.

SímboloParâmetrosComportamento padrãoRetornoLança ou falha comNotas
new PinnedCurlTransport(ResponseFactoryInterface $responseFactory, StreamFactoryInterface $streamFactory, array $pinnedIps = [], array $pinnedPublicKeys = [], int $timeoutSeconds = 30)Factories de PSR-17, IPs com pin, chaves públicas com pin, timeout.Sem pins e um timeout de 30 segundos.PinnedCurlTransportNenhuma esperada.Use somente quando o pinning no nível do cURL for necessário.
PinnedCurlTransport::sendRequest(RequestInterface $request)Requisição de PSR-7.Envia via cURL com o timeout e os controles de pinning configurados.ResponseInterfaceExceções de transporte de PSR-18.Use somente quando os clientes HTTP do framework não conseguem aplicar a mesma política de pinning.
PinnedCurlTransport::buildCurlOptions(RequestInterface $request, string $host, int $port)Requisição, host de destino, porta de destino.Monta o array de opções do cURL usado por sendRequest().arrayErros de requisição inválida ou de configuração de pin.Hook de teste e diagnóstico de baixo nível.
LocalRendererInterface::render(string $html, array $options = [])HTML e opções do renderer.Apenas contrato; a implementação define os valores padrão.stringErros de renderização específicos da implementação.Usado como fallback local quando a renderização pelo Worker está indisponível.
LocalRendererFactoryInterface::create()nenhum.Cria uma implementação de renderer local.LocalRendererInterfaceErros de factory ou de dependência.Mantém a construção do renderer de fallback fora de CloudflareHtmlRenderer.
  • Trate a URL do Worker como um limite de rede. Valide o destino, o tamanho e a autenticação antes de renderizar.
  • Use os resultados da proteção de API como saídas de política, não como fluxo de controle por exceção.
  • Os uploads no R2 retornam resultados estruturados de sucesso ou de erro; trate ambos os caminhos.