Laravel'e Symfony Component Entegrasyonu

## Symfony Component'leri ile Laravel Entegrasyonu Laravel, temelinde birçok Symfony component'ini kullanır. HTTP katmanından konsol komutlarına, eve...

Laravel'e Symfony Component Entegrasyonu

Symfony Component'leri ile Laravel Entegrasyonu

Laravel, temelinde birçok Symfony component'ini kullanır. HTTP katmanından konsol komutlarına, event dispatcher'dan Finder'a kadar pek çok yapı taşı doğrudan Symfony ekosisteminden gelir. Bu rehber, orta seviye bir Laravel geliştiricisinin mevcut bir Laravel uygulamasına bağımsız bir Symfony component'ini nasıl ekleyeceğini, servis container'ına nasıl bağlayacağını ve yaygın hatalardan nasıl kaçınacağını anlatır.

Önkoşullar

  • Composer ile çalışan bir Laravel uygulaması.
  • Laravel'in servis container, service provider ve facade mekanizmalarına aşinalık.
  • PHP 8.x çalıştıran bir ortam.

Laravel sürümüne özel davranışlar bu rehberde varsayılmamıştır; anlatılan yöntem, Laravel'in servis container'ı ve service provider yapısını kullanan tüm modern sürümlerde geçerlidir. Kullanacağınız Symfony component'inin kendi minimum PHP sürümünü ayrıca kontrol edin.

Laravel Zaten Hangi Symfony Parçalarını Kullanıyor?

Laravel'in composer.json dosyasını incelediğinizde symfony/console, symfony/http-foundation, symfony/http-kernel, symfony/finder, symfony/process gibi paketleri bağımlılık olarak görürsünüz. Bu, iki önemli sonuç doğurur:

  1. Bu paketler zaten yüklü olduğundan, aynı component'i ayrıca kurmanız gerekmez.
  2. Laravel'in kullandığı sürüm aralığı, sizin doğrudan kullanacağınız sürümü de sınırlar. composer require ile farklı bir major sürüm çekmeye çalışırsanız bağımlılık çakışması yaşarsınız.

Bu yüzden entegrasyona başlamadan önce composer show symfony/<component> komutuyla yüklü sürümü doğrulayın.

Bağımsız Bir Component Ekleme

Laravel'in hâlihazırda kullanmadığı bir component (örneğin symfony/serializer veya symfony/workflow) eklemek istediğinizi varsayalım:

composer require symfony/serializer

Composer, Laravel'in diğer Symfony bağımlılıklarıyla uyumlu bir sürümü çözmeye çalışır. Çakışma bildirirse, Laravel'in kilitlediği sürüm aralığına uyan bir sürüm belirtmeniz gerekir.

Service Provider ile Container'a Bağlama

Symfony component'lerinin çoğu framework'ten bağımsızdır; yani kendi başlarına bir servis container'ı bilmezler. Laravel tarafında bunları container'a kaydetmek sizin sorumluluğunuzdadır. Tipik yaklaşım bir service provider içinde singleton veya bind kullanmaktır.

Örnek olarak Symfony Serializer'ı yapılandıralım:

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;

class SerializerServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(Serializer::class, function () {
            $encoders = [new JsonEncoder()];
            $normalizers = [new ObjectNormalizer()];

            return new Serializer($normalizers, $encoders);
        });
    }
}

Provider'ı bootstrap/providers.php (veya sürümünüze göre config/app.php) içine ekleyin. Artık Serializer sınıfını constructor üzerinden enjekte edebilir veya app(Serializer::class) ile çözebilirsiniz.

Beklenen Davranış

singleton kaydı sayesinde Serializer örneği uygulama yaşam döngüsü boyunca bir kez oluşturulur ve aynı örnek paylaşılır. Eğer her çözümlemede yeni bir örnek istiyorsanız singleton yerine bind kullanın. Bu ayrım özellikle durum tutan (stateful) component'lerde önemlidir; yanlış seçim, istekler arası beklenmeyen veri sızıntısına yol açabilir.

Facade ile Erişim (İsteğe Bağlı)

Container kaydını kısa yoldan çağırmak isterseniz bir facade tanımlayabilirsiniz:

namespace App\Facades;

use Illuminate\Support\Facades\Facade;

class Serializer extends Facade
{
    protected static function getFacadeAccessor(): string
    {
        return \Symfony\Component\Serializer\Serializer::class;
    }
}

Facade'ler yalnızca container'daki bir anahtarı temsil eder; ek bir sihir içermez. Test edilebilirlik açısından constructor injection genellikle daha açık bir tercihtir.

Yaygın Hatalar

Sürüm çakışması. Laravel'in kilitlediği bir Symfony paketinin farklı major sürümünü kurmaya çalışmak. Çözüm: composer why-not symfony/<paket> <sürüm> ile engeli tespit edin.

Config'i görmezden gelmek. Bazı component'ler (örneğin Serializer normalizer'ları) yapılandırma gerektirir. Varsayılan kurulumla beklediğiniz çıktıyı alamazsanız, önce normalizer/encoder listesini kontrol edin.

Component'i Laravel'e özgü sanmak. Symfony component'leri framework bağımsızdır; config/ dosyalarından otomatik okumazlar. Yapılandırmayı provider içinde elle yapmanız gerekir.

Container'da yanlış yaşam döngüsü. Durum tutan bir servisi singleton yapmak, uzun ömürlü worker ortamlarında (queue worker, Octane) istekler arası durum taşınmasına neden olabilir.

Güvenlik Notları

  • Deserialization. Serializer veya benzeri component'lerle dış kaynaktan gelen veriyi çözerken unserialize tabanlı yapılardan kaçının. JSON gibi metin tabanlı formatları tercih edin; nesne enjeksiyonuna açık allowed_classes gibi ayarları bilinçli yapılandırın.
  • Dosya sistemi component'leri. symfony/finder veya symfony/filesystem ile kullanıcı girdisinden türetilen yollar üzerinde işlem yapıyorsanız path traversal riskini hesaba katın ve yolları doğrulayın.
  • Process component'i. symfony/process ile dış komut çalıştırırken kullanıcı girdisini doğrudan komut dizisine eklemeyin; argümanları ayrı dizi elemanları olarak geçirin.

Ne Zaman Symfony Component'i, Ne Zaman Laravel Yapısı?

Laravel'in sunduğu bir çözüm (örneğin Illuminate\Support\Facades\Http, Illuminate\Support\Str) ihtiyacınızı karşılıyorsa önce onu değerlendirin; framework ile uyum ve dokümantasyon açısından daha az sürtünme yaratır. Symfony component'i tercih etmenin anlamlı olduğu durumlar:

  • İhtiyacınız Laravel'in kapsamadığı bir alandaysa (örneğin karmaşık iş akışları için symfony/workflow).
  • Framework'ten bağımsız, taşınabilir bir kod parçası yazıyorsanız.
  • Component'in olgun ekosistemi ve dokümantasyonu projeniz için belirgin avantaj sağlıyorsa.

Sonuç

Laravel ile Symfony component'lerini birleştirmek, framework'ün zaten kurduğu altyapıyı genişletmekten ibarettir: paketi doğru sürümle kurun, service provider içinde container'a bağlayın, yaşam döngüsünü bilinçli seçin ve güvenlik sınırlarını (deserialization, dosya yolları, dış komutlar) net çizin. Bu dört adım, çoğu entegrasyonun ortak çerçevesidir.

İLGİLİ İÇERİKLER

Bunları da Okumak İsteyebilirsiniz