Laravel 11, son yıllarda oldukça pratik bir yardımcıyı sessizce tanıttı: defer().
Bu, HTTP yanıtı gönderildikten sonra kod çalıştırmanıza olanak tanır — ek bir queue worker, Redis veya Supervisor yapılandırması gerekmez. Sadece:
defer(fn () => Metrics::recordOrder($order));
Kullanıcı yanıtı anında alır. Closure, daha sonra çalışır. Sıfır ek altyapı.
Ama birçok geliştirici bunu ya göz ardı ediyor ya da yanlış kullanıyor. İşte şeffaf bir analiz.
Tek Satırlık Kural
Tek Satırlık Kural
-
defer()→ “Bu bir çöküşte kaybolursa sorun değil” - Queue Job → “Bu işlem başarılı olmalı, başarısız olursa tekrar denensin”
defer() Gerçekte Ne Yapar
defer() Gerçekte Ne Yapar
HTTP yanıtı gönderildikten sonra aynı PHP sürecinde bir closure çalıştırır.
use function Illuminate\Support\defer;
Route::post('/orders', function (Request $request) {
$order = Order::create($request->validated());
defer(fn () => Metrics::recordOrder($order)); // yanıt sonrasında çalışır
return response()->json($order, 201); // hemen döner
});
Anahtar davranışlar:
- Yanıt
4xxveya5xxise yürütmeyi atlar (bunu aşmak için->always()kullanabilirsiniz) - İsimlendirilebilir ve iptal edilebilir:
defer(fn () => ..., 'name')+defer()->forget('name') - Sunucu çökmesi durumunda kaybolur — herhangi bir yerde saklanmaz
Sürüm desteği: Sadece Laravel 11+ için geçerlidir. Laravel 10 veya öncesinde mevcut değildir.
Hızlı Karşılaştırma Tablosu
Hızlı Karşılaştırma Tablosu
| Özellik | Queue Job | defer() |
|---|---|---|
| Queue worker gerektirir | ✅ Evet | ❌ Hayır |
| Redis / DB sürücüsü gerektirir | ✅ Evet | ❌ Hayır |
| Depolama alanına kaydedilir | ✅ Evet | ❌ Hayır |
| Başarısızlıkta tekrar dener | ✅ Evet | ❌ Hayır |
| Gecikmeli yürütme | ✅ Evet | ❌ Hayır |
| İzleme (Horizon) | ✅ Evet | ❌ Hayır |
| Sıfır kurulum | ❌ Hayır | ✅ Evet |
| Yanıttan sonra çalışır | ayrı bir süreç | ✅ aynı süreç |
defer() için şunları kullanın:
defer() için şunları kullanın:
- Bir sipariş sonrası analitik kaydetme
- Sayfa görüntüleme / “son göründü” sayaçlarını artırma
- Bir kaynak oluşturulduktan sonra cache anahtarını boşaltma
- Önemli olmayan iç Slack bildirimleri
- Hafif denetim kaydı yazımları
Queue Jobs için şunları kullanın:
Queue Jobs için şunları kullanın:
- İşlemcileri kaybetmemesi gereken iletişim e-postaları
- Ödeme webhook’ları ve API çağrıları (tekrar denemesi gerekenler)
- Görüntü/dosya işlemleri (CPU yoğun)
- Gecikmeli görevler (“24 saat içinde hatırlatmayı gönder”)
- Horizon veya Telescope aracılığıyla izlenen her şey
⚠️ Swoole Sorunu
⚠️ Swoole Sorunu
Swoole veya FrankenPHP kullanıyorsanız, her zaman Laravel’in defer() fonksiyonunu açıkça içe aktardığınızdan emin olun:
// Swoole'da YANLIŞ — Swoole'un defer()ini çağırır, Laravel'in değil
defer(fn () => Metrics::record($data));
// DOĞRU
use function Illuminate\Support\defer;
defer(fn () => Metrics::record($data));
Swoole, kendi global defer() fonksiyonuna sahiptir. Çatışma sessiz bir şekilde gerçekleşir ve size saatler kaybettirir.
Deferred Fonksiyonlarının Test Edilmesi
Deferred Fonksiyonlarının Test Edilmesi
public function test_order_records_metrics(): void
{
$this->withoutDefer(); // deferred closure'ları hemen çalıştırır
Metrics::shouldReceive('recordOrder')->once();
$this->postJson('/api/orders', ['product_id' => 1, 'qty' => 2])
->assertStatus(201);
}
Tam yazı
Tam yazı
Tam karar rehberi için (8 soruluk karar matrisini, Laravel 13 notlarını ve tam kod örneklerini de içeren):
👉 pola5h.github.io/blog/laravel-queue-vs-defer/
Projelerinizde defer() fonksiyonunu ne amaçla kullanıyorsunuz? Yorumlarınızı bırakın 👇
Kaynak: Orijinal Makale


