PHP İstek Yaşam Döngüsünün Sonu
On yıllar boyunca, PHP’nin en büyük mimari avantajı “paylaşmayan” mimarisiydi. Bir istek gelir, framework çalışır, veritabanına sorgu gönderilir, cevap yollanır ve ardından tüm PHP süreci sona erer. Her bir değişken, singleton ve bellek tahsisi temizlenir. Bu, son derece güvenlidir; ancak her istekte framework’ün sıfırdan başlatılması doğası gereği yavaştır.
B2B SaaS platformlarını Smart Tech Devs’de saniyede binlerce isteğe ölçeklendirmek için Laravel Octane kullanıyoruz (Swoole veya FrankenPHP motoruyla desteklenmektedir). Octane, Laravel framework’ünü bir kez başlatır ve onu RAM’de canlı tutar, gelen isteklere anında yanıt verir. Laravel’i son derece hızlı hale getirir—ancak “paylaşmayan” güvenlik ağını yok eder. Bu, ürkütücü bir zafiyet olan State Leakage‘i beraberinde getirir.
Çok Kiracılı State Leakage Tuzağı
Eğer PHP süreci asla sona ermezse, bellek istekler arasında kalıcı hale gelir. Dikkat etmezseniz, Kullanıcı A’nın isteğinden gelen veriler, Kullanıcı B’nin isteğine sızabilir.
Kendi TenantService sınıfınızı bir Singleton olarak Service Provider’da kaydettiğinizi düşünün. Standart Laravel’de bu tamamen uygundur. Ancak Octane’de bu kritik bir veri ihlaline yol açar.
// ❌ ANTI-PATTERN: Octane'de tehlikeli!
namespace App\Services;
class TenantService
{
protected $currentTenant;
public function setTenant($tenant)
{
$this->currentTenant = $tenant;
}
public function getTenant()
{
return $this->currentTenant;
}
}
Eğer Kullanıcı A API’nizi kullanıyorsa, middleware $currentTenant="Acme Corp" olarak ayarlanır. Bir milisaniye sonra, Kimlik doğrulama jetonunu unutan Kullanıcı B, API’ye aynı PHP işçi iş parçacığında erişir. TenantService önceki istekte yaşamaya devam eden bir singleton olduğundan, hâlâ ‘Acme Corp’ u hatırlıyor. Kullanıcı B, Kullanıcı A’nın verilerine yetkisiz erişim sağlıyor.
Kurumsal Çözüm: State’i Temizleme
Laravel Octane için güvenli bir mimari oluşturmak amacıyla, her istektan sonra durum bilgisi taşıyan singleton’ları veya statik değişkenleri açıkça temizlemelisiniz. Laravel Octane, config/octane.php dosyasında bunun için özel bir dinleyici mekanizması sunar.
Adım 1: Temizlenebilir Bir Servis Mimarisi Kurma
Servisimize durumu temizlemek için bir flush() metodu ekliyoruz.
// ✅ KURUMSAL PATTERN
namespace App\Services;
class TenantService
{
protected $currentTenant;
public function setTenant($tenant) { $this->currentTenant = $tenant; }
public function getTenant() { return $this->currentTenant; }
// Reset metodunu ekleyin
public function flush()
{
$this->currentTenant = null;
}
}
Adım 2: Flush Dinleyicisini Kaydetme
config/octane.php içerisinde, Octane’nin her HTTP isteği tamamlandıktan sonra bu flush metodunu otomatik olarak çağırmasını sağlıyoruz.
// config/octane.php
'listeners' => [
RequestTerminated::class => [
// Veritabanı sorgu günlüklerini, kimlik doğrulama durumunu vb. temizle (Gömülü)
FlushSessionState::class,
FlushAuthenticationState::class,
// Temizlenmesi gereken özel servisimizi kaydedin
function ($event) {
app(\App\Services\TenantService::class)->flush();
},
],
],
Mühendislik ROI’si
Laravel Octane’e geçiş, API yanıt sürelerinizi 150ms’den 15ms’ye düşürebilir. Ancak hız, güven olmadan bir yükümlülüktür. Singleton’larınızı, statik özelliklerinizi ve küresel durumu acımasızca denetleyerek ve Octane’in flush dinleyicilerini kullanarak, Node/Go’nun çarpıcı hızını Laravel’in zarif geliştirici deneyimi ile birleştirip, güvenli bir şekilde büyük ölçekli bir SaaS oluşturabilirsiniz.
Kaynak: Orijinal Makale


