Üretimde kullanım — yerel yedek, telemetri, arşivleme, koruma
Bir bakışta
“Bir bakışta” başlıklı bölümBu sayfa, temel işleme akışının ötesindeki dört üretim konusunu kapsar: yerel yedek, kenar telemetrisi, Cloudflare R2 arşivlemesi ve gelen application programming interface (API) koruma katmanı. Her bölüm doğrulanmış sınıf davranışına dayanır.
Yerel yedek
“Yerel yedek” başlıklı bölümWorker erişilemediğinde ve fallbackToLocal değeri true olduğunda, köprü işlemeyi yerel bir işleyiciye devreder. Bu işleyiciyi LocalRendererFactoryInterface üzerinden sağlayın. Köprü yerel işleyiciyi gecikmeli olarak oluşturur; bu nedenle fabrikanın create() metodu yalnızca yedek yolunda çalışır.
<?php
declare(strict_types=1);
use NextPDF\Cloudflare\Contract\LocalRendererFactoryInterface;use NextPDF\Cloudflare\Contract\LocalRendererInterface;
final class ArtisanLocalRendererFactory implements LocalRendererFactoryInterface{ public function __construct( private readonly \NextPDF\Artisan\ChromeHtmlRenderer $chrome, ) {}
public function create(): LocalRendererInterface { return new readonly class($this->chrome) implements LocalRendererInterface { public function __construct( private \NextPDF\Artisan\ChromeHtmlRenderer $chrome, ) {}
/** @param array<string, mixed> $options */ public function render(string $html, array $options = []): string { // Delegate to the local Chrome renderer; return raw PDF bytes. return $this->chrome->renderToString($html, $options); } }; }}Fabrikayı işleyiciye bağlayın:
use NextPDF\Cloudflare\CloudflareHtmlRenderer;
$renderer = new CloudflareHtmlRenderer( config: $config, httpClient: $httpClient, requestFactory: $httpFactory, streamFactory: $httpFactory, logger: $logger, localRendererFactory: new ArtisanLocalRendererFactory($chrome), responseFactory: $httpFactory,);Yedek yol çalıştığında, sonuçtaki renderLocation değeri sabit local dizgesidir ve heightPt değeri 0.0 olur. Yerel yol bir kenar konumu veya ölçülmüş yükseklik bildirmez. Köprü, istenen genişliği yerel işleyiciye widthPt seçenek anahtarı aracılığıyla iletir.
Yedek karar mantığı
“Yedek karar mantığı” başlıklı bölümDoğrudan CloudflareHtmlRenderer sınıfından okunur:
| Durum | Sonuç |
|---|---|
Yapılandırma eksik, fallbackToLocal: false | CloudflareNotAvailableException |
Yapılandırma eksik, fallbackToLocal: true, fabrika bağlanmış | Yerel işleme |
| Worker bir taşıma hatası fırlatır, yedek etkin, fabrika bağlanmış | Yerel işleme, günlüğe kaydedilir: önce warning, ardından info |
| Worker hata fırlatır, yedek etkin, Artisan kurulu, fabrika yok | CloudflareNotAvailableException, eksik fabrikayı belirtir |
| Worker hata fırlatır, yedek etkin, Artisan kurulu değildir | CloudflareNotAvailableException, eksik paketi belirtir |
| Worker bir Hypertext Transfer Protocol (HTTP) hatası ya da bozuk gövde döndürür | CloudflareRenderException, asla yedeğe geçmez |
Son satır kritiktir. Hata döndüren bir Worker, erişilebilirlik hatası değil, işleme hatası üretir. Köprü bunu yeniden fırlatır; böylece kodunuz bozuk bir işlemeyi erişilemeyen bir kenardan ayırt edebilir.
Kenar telemetrisi
“Kenar telemetrisi” başlıklı bölümİkili yol üzerinden başarıyla tamamlanan her işleme, yanıt başlıklarından gelen telemetriyi içerir:
$result = $renderer->render($html);
$logger->info('edge render', [ 'edge' => $result->renderLocation, // e.g. 'TPE', 'NRT' 'render_time_ms' => $result->renderTimeMs, 'content_px' => $result->contentHeightPx, 'pdf_bytes' => $result->size(),]);İşleyici renderLocation değerini CF-Ray yanıt başlığından okur ve son tireden sonraki bölümü alır. CF-Ray: 8abc123def456-TPE için konum TPE olur. Başlık yoksa konum boş bir dizgedir. JavaScript Object Notation (JSON) yanıt yolunda ise değer bunun yerine JSON renderLocation alanından gelir. Bu değerleri platform garantisi olarak değil, Worker’dan gelen gözlemlenebilirlik sinyalleri olarak değerlendirin.
R2 arşivlemesi
“R2 arşivlemesi” başlıklı bölümR2ArchiveManager, Portable Document Format (PDF) baytlarını Amazon Simple Storage Service (S3) uyumlu API üzerinden Cloudflare R2’ye yükler ve istekleri Amazon Web Services (AWS) Signature V4 ile imzalar.
use NextPDF\Cloudflare\R2ArchiveConfig;use NextPDF\Cloudflare\R2ArchiveManager;
$r2 = new R2ArchiveManager( config: new R2ArchiveConfig( bucketName: 'pdf-archive', accountId: getenv('CF_ACCOUNT_ID') ?: '', accessKeyId: getenv('R2_ACCESS_KEY_ID') ?: '', secretAccessKey: getenv('R2_SECRET_ACCESS_KEY') ?: '', pathPrefix: 'invoices/', ), httpClient: $httpClient, requestFactory: $httpFactory, streamFactory: $httpFactory,);
$upload = $r2->upload($result->pdfData, 'invoice-2026-0042.pdf', [ 'tenant' => 'acme',]);
if (!$upload->success) { $logger->error('r2 upload failed', ['error' => $upload->error]);}Davranış, R2ArchiveManager ve R2ObjectKey üzerinden doğrulanır:
- Nesne anahtarı tarihe göre bölümlere ayrılır:
<pathPrefix><Y>/<m>/<d>/<sanitized-filename>, örneğininvoices/2026/05/18/invoice-2026-0042.pdf. - Dosya adı temizlenir:
basename()yol geçişini kaldırır; ardından boş baytlar ve denetim karakterleri (\x00–\x1f,\x7f) çıkarılır. Boş bir sonuçdocument.pdfolur. - Özel meta veriler
x-amz-meta-<lowercased-key>başlıkları olarak gönderilir ve V4 imzalı başlık kümesine dahil edilir. - Boyutu
maxFileSizeBytesdeğerinden (varsayılan104857600) büyük olan dosyalar, herhangi bir istek yapılmadan önce reddedilir; döndürülenR2UploadResultnesnesindesuccess: falsebulunur. R2UploadResult::isValid()metodu geçerli sonuç içinsuccess, boş olmayan birkeyve boş olmayan biretaggerektirir.
Önceden imzalanmış indirme URL’leri
“Önceden imzalanmış indirme URL’leri” başlıklı bölüm$url = $r2->generateSignedUrl('invoices/2026/05/18/invoice-2026-0042.pdf', 900);generateSignedUrl(), AWS Signature V4 sorgu imzası taşıyan bir GET URL’si oluşturur; bu URL’de denetlediğiniz bir X-Amz-Expires değeri (varsayılan 3600 saniye) bulunur. Kanonik istek, UNSIGNED-PAYLOAD içerik karması işaretçisini kullanır. Sorgu imzası taşıyan bir okuma URL’si bu biçimi kullanır; çünkü gövde, imzalı isteğin bir parçası değildir. Bu açıklama, R2ArchiveManager sınıfından okunduğu hâliyle paketin uygulanmış imzalama davranışını anlatır. AWS Signature Version 4’ü, bir standards development organization (SDO) standardı değil, Amazon’un hizmet belgeleri tanımlar; bu nedenle burada normatif bir madde sabitlenmemiştir. Nesne erişim anahtarları #[SensitiveParameter] ile işaretlidir; bunları günlüklerin dışında tutun.
Genel URL’ler
“Genel URL’ler” başlıklı bölümR2UploadResult::publicUrl($customDomain), bir etki alanı sağlamadığınızda yalın anahtarı, sağladığınızda ise https://<domain>/<key> biçimini döndürür. Sağlanan etki alanında şema yoksa, bir Hypertext Transfer Protocol Secure (HTTPS) şeması ekler. Özel bir paketi herkese açık hâle getirmez; bu, R2 paketi yapılandırması olarak kalır.
Gelen API koruması
“Gelen API koruması” başlıklı bölümApiProtection, Worker’ın önündeki bir PHP ağ geçidine ulaşan işleme isteklerine uyguladığınız katmandır. Denetimleri sabit bir sırayla yapar: önce API anahtarı, ardından yük boyutu, ardından hız sınırı.
use NextPDF\Cloudflare\ApiKeyValidator;use NextPDF\Cloudflare\ApiProtection;use NextPDF\Cloudflare\ApiProtectionConfig;
$protection = new ApiProtection( config: new ApiProtectionConfig( maxRequestsPerMinute: 30, maxRequestsPerHour: 500, maxPayloadSizeBytes: 5_000_000, requireApiKey: true, ), keyValidator: new ApiKeyValidator([getenv('GATEWAY_API_KEY') ?: '']),);
$decision = $protection->checkRequest( clientId: $clientIp, payloadSize: strlen($requestBody), apiKey: $request->getHeaderLine('X-Api-Key'),);
if (!$decision->allowed) { http_response_code(429); foreach ($decision->toHeaders() as $name => $value) { header("{$name}: {$value}"); } echo $decision->denialReason; exit;}Doğrulanan davranış:
- Sıra şöyledir: API anahtarı → yük boyutu → hız sınırı. İlk başarısız denetim, belirli bir
denialReasonile akışı kısa devreye uğratır. ApiKeyValidator::validate(), zamanlama açısından güvenli karşılaştırma içinhash_equals()kullanır ve boş bir anahtarı reddeder.validateHashed(), statik anahtar depolaması için Secure Hash Algorithm 256-bit (SHA-256) karmalarıyla karşılaştırır. Anahtar parametreleri#[SensitiveParameter]taşır.- Hız sınırı deposu işlem başına bellek içindedir. Dakika başına bir pencereyi (
rateLimitWindowSeconds, varsayılan60) ve saat başına bir pencereyi (sabit3600saniye) izler. Worker’lar veya yeniden başlatmalar arasında kalıcı değildir. Sınırları işlemler arasında paylaşmak için bu katmanın önüne paylaşılan bir depo yerleştirin. ApiProtectionResult::toHeaders(), her zamanX-Content-Type-Options: nosniffveX-Frame-Options: DENYekler ve hız sınırı başlıklarını (X-RateLimit-Remaining,X-RateLimit-Resetve reddedildiğinde ek olarakRetry-After) birleştirir.
Önce işle, sonra imzala
“Önce işle, sonra imzala” başlıklı bölümBu köprü PDF’leri imzalamaz. Bir üretim imzalama hattı oluşturmak için kenarda işleyin, ardından döndürülen baytları imzalama motoruyla imzalayın:
render()→CloudflareRenderResult::$pdfData.- Döndürülen
$pdfDatadeğerininextpdf/corepaketine (veya PDF Advanced Electronic Signatures (PAdES) B-B imzalama için NextPDF Pro’ya) verin. Uzun vadeli doğrulama profilleri bir Enterprise yeteneğidir; bu çekirdek köprü bu yeteneklerden hiçbirini sağladığını iddia etmez.
İmzalama adımını kendi işleminizde tutun; böylece imzalama anahtarı asla kenar sınırını geçmez.
Ayrıca bkz.
“Ayrıca bkz.” başlıklı bölüm- /integrations/cloudflare/security-and-operations/ — sabitleme, server-side request forgery (SSRF) savunması, gizli anahtar döndürme ve operasyonel başvuru kılavuzu.
- /integrations/cloudflare/troubleshooting/ — arıza modu kataloğu.
- /integrations/cloudflare/configuration/ — tüm alanlar ve varsayılanlar.