BG MVC Model View Controller eğitim serisi yayında...

Ana sayfa > Programlama > Symfony Framework > Symfony mimarisi

Symfony mimarisi

Bu bölümde, Symfony'nin mimari yapısını ele alacağız.

Dizin yapısı

Bir Symfony uygulamasının dizin yapısı oldukça esnektir, ancak önerilen yapı şu şekildedir:

app/ Uygulamanın konfigürasyonu, şablonlar ve çeviriler.
bin/ Çalıştırabilir dosyalar (örneğin, bin/console).
src/ Projenin PHP kodu.
tests/ Otomatik testler.
var/ Üretilen dosyalar (önbellek, günlükler, vb.).
vendor/ Üçüncü-parti programlar.
web/ Web ana dizini.

web/ dizini

Web kök dizini, resimler, stil sayfası ve JavaScript dosyaları gibi tüm public ve statik bulunduğu yerdir. Aynı zamanda, burada üretim denetleyicisi gibi ön denetleyiciler de (uygulamanızdaki tüm istekleri işleyen dosya) bulunur:


// web/app.php
require_once __DIR__.'/../var/bootstrap.php.cache';
require_once __DIR__.'/../app/AppKernel.php';

use Symfony\Component\HttpFoundation\Request;

$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();

Denetleyici ilk önce bir çekirdek sınıfı (bu durumda AppKernel) kullanarak uygulama önyüklemesi yapar. Ardından, PHP'nin genel değişkenlerini kullanarak Request nesnesi oluşturur ve onu çekirdeğe aktarır. Son adım, çekirdek tarafından döndürülen yanıt içeriğini kullanıcıya geri göndermektir.

app/ dizini

AppKernel sınıfı, uygulama yapılandırmasının ana giriş noktasıdır ve bu nedenle, app/ dizininde bulunur.

Bu sınıfın iki metod çalıştırması gerekir:

registerBundles(): Uygulamayı çalıştırmak için gereken tüm paketleri içeren bir dizin döndürmelidir.

registerContainerConfiguration(): Uygulama yapılandırmasını yükler.

Otomatik yükleme, otomatik olarak Composer tarafından gerçekleştirildiğinden, hiçbir şey yapmadan herhangi bir PHP sınıfını kullanabilirsiniz. Bütün bağlı programlar vendor dizini altında bulunur, ancak bu yalnızca bir kuraldır. Onları istediğiniz yerde, sunucunuzda veya yerel olarak projelerinizde depolayabilirsiniz.

Paket (Bundle) sistemi

Bu bölümde Symfony'nin en büyük ve en güçlü özelliklerinden biri ele alınacaktır: Paket sistemi. Bir paket, diğer yazılımlarda bulunan bir eklenti gibidir. Eklenti olarak değil de, paket olarak adlandırılmasının nedeni, Symfony'de çekirdeğin temel özelliklerinden uygulamanız için yazdığınız koda kadar her şeyin bir paket olarak ele alınmasıdır.

Uygulamanız için yazdığınız tüm kodlar paket halinde düzenlenmiştir. Symfony açısından bakıldığında bir paket, tek bir özelliği (blog, forum, ...) uygulayan ve diğer geliştiricilerle kolayca paylaşılabilen yapılandırılmış bir dosya kümesidir (PHP dosyaları, stil sayfası, JavaScriptler, resimler, ...).

Paketler, Symfony'de en önemli öğelerdir. Bu sistem size, diğer geliştiriciler tarafından hazırlanmış paketlerdeki önceden oluşturulmuş özellikleri kullanmanızda veya kendi paketlerinizi dağıtmada için esneklik sağlar. Uygulamanızda hangi özelliklerin etkinleştirileceğini seçip bunları istediğiniz şekilde optimize etmeyi kolaylaştırır. Çalışmanızın sonunda, uygulama kodunuz çekirdek çerçevesinin kendisi kadar önemli hale gelir.

Symfony, halihazırda, uygulamanızı geliştirmeye başlamanız için kullanabileceğiniz bir AppBundle içeriyor. Sonra, uygulamayı yeniden kullanılabilir bileşenlere bölmeniz gerekiyorsa kendi paketlerinizi oluşturabilirsiniz.

Paketin (Bundle) kaydedilmesi

Bir uygulama, AppKernel sınıfının registerBundles() metodunda tanımlanan paketlerden oluşur. Her paket, onu tanımlayan tek bir Bundle sınıfı içeren bir dizindir:


// app/AppKernel.php
public function registerBundles()
{
    $bundles = array(
        new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
        new Symfony\Bundle\SecurityBundle\SecurityBundle(),
        newSymfony\Bundle\TwigBundle\TwigBundle(),
        new Symfony\Bundle\MonologBundle\MonologBundle(),
        new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
        new Symfony\Bundle\DoctrineBundle\DoctrineBundle(),
        new Symfony\Bundle\AsseticBundle\AsseticBundle(),
        new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
        new AppBundle\AppBundle(),
    );

    if (in_array($this->getEnvironment(), array('dev', 'test'))) {
        $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
        $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle();
        $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle();
    }
	
    return $bundles;
}

AppBundle'a ek olarak, çekirdeğin Symfony'nin bir parçası olan FrameworkBundle, DoctrineBundle, SwiftmailerBundle ve AsseticBundle gibi diğer paketleri de etkinleştirdiğine dikkat edin.

Paketin (Bundle) yapılandırılması

Her paket, YAML, XML veya PHP ile yazılmış yapılandırma dosyaları aracılığıyla özelleştirilebilir. Varsayılan Symfony yapılandırmasının örneğine göz atın:


# app/config/config.yml
imports:
    - { resource: parameters.yml }
    - { resource: security.yml }
    - { resource: services.yml }
	
framework:
    #esi: ~
    #translator: { fallbacks: ['%locale%'] }
    secret: '%secret%'
    router:
        resource: '%kernel.root_dir%/config/routing.yml'
        strict_requirements: '%kernel.debug%'
    form: true
    csrf_protection: true
    validation: { enable_annotations: true }
    templating: { engines: ['twig'] }
    default_locale: '%locale%'
    trusted_proxies: ~
    session: ~
	
# Twig Configuration
twig:
    debug: '%kernel.debug%'
    strict_variables: '%kernel.debug%'
	
# Swift Mailer Configuration
swiftmailer:
    transport: '%mailer_transport%'
    host: '%mailer_host%'
    username: '%mailer_user%'
    password: '%mailer_password%'
    spool: { type: memory }
	
# ...

Framework, twig ve swiftmailerk gibi birinci seviye girişleri, belirli bir paket için yapılandırmayı tanımlar. Örneğin, swiftmailer SwiftmailerBundle'ı yapılandırırken, Framework FrameworkBundle'ı yapılandırır.

Her ortam, belirli bir yapılandırma dosyası sağlayarak varsayılan yapılandırmayı geçersiz kılabilir. Örneğin, dev ortamı, ana yapılandırmayı (diğer bir deyişle config.yml) yükleyen config_dev.yml dosyasını yükler ve daha sonra bazı hata ayıklama araçları eklemek için onu değiştirir:


# app/config/config_dev.yml
imports:
    - { resource: config.yml }
	
framework:
    router: { resource: '%kernel.root_dir%/config/routing_dev.yml' }
    profiler: { only_exceptions: false }

web_profiler:
    toolbar: true
    intercept_redirects: false

# ...

Paketin (Bundle) genişletilmesi

Kodunuzu organize etmenin ve yapılandırmanın yanı sıra, bir paketten başka bir alt paket oluşturabilirsiniz. Paket kalıtımı, kendisinden paket türetilen paketin denetçilerini, şablonlarını veya dosyalarından herhangi birisini özelleştirmek için mevcut paketi geçersiz kılmanıza izin verir.

Mantıksal dosya isimleri

Bir paketteki bulunan bir dosyaya erişim sağlamak istediğinizde, bu yazım şeklini kullanın: @BUNDLE_NAME/path/to/file; Symfony @BUNDLE_NAME değerinden paketin gerçek yolunu elde edecektir. Örneğin, Symfony AppBundle'ın yerini bildiği için, @AppBundle/Controller/DefaultController.php mantıksal yolunu src/AppBundle/Controller/DefaultController.php değerine dönüştürecektir.

Mantıksal denetleyici isimleri

Denetleyiciler için,eylemlere çağrı yapmak için BUNDLE_NAME:CONTROLLER_NAME:ACTION_NAME yapısını kullanmanız gerekir. Örneğin, AppBundle:Default:index komutu, AppBundle\Controller\DefaultController sınıfından indexAction() metodunu çağırır.

Paketleri genişletme

Bu yöntemleri izlerseniz, dosyaları, denetleyicileri veya şablonları geçersiz kılmak için paket kalıtım yöntemini kullanabilirsiniz. Örneğin, AppBundle'ı geçersiz kılan NewBundle adlı bir paket oluşturduğunuzda, Symfony AppBundle:Default:index denetleticisini yüklediğinde, önce NewBundle içindeki DefaultController sınıfını arar ve yoksa AppBundle içine bakar. Bu, bir paketin başka bir paketin hemen hemen herhangi bir bölümünü geçersiz kılabileceği anlamına gelir!

Vendor kullanımı

Uygulamanızın üçüncü parti kütüphanelere bağımlı olarak çalışmaktadır. Bunlar vendor/ dizininde saklanmalıdır. Bu dizinde herhangi bir şeye dokunmamalısınız, çünkü yalnızca Composer tarafından yönetilmektedir. Bu dizin aynı zamanda Symfony kitaplıklarını, SwiftMailer kitaplığını, Doctrine ORM'yi, Twig şablonlama sistemini ve diğer bazı üçüncü parti kitaplıklarını ve paketlerini içeriyor.

Önbellek ve Günlükler

Symfony uygulamaları çeşitli biçimlerde (YAML, XML, PHP, vb.) tanımlanan birkaç yapılandırma dosyası içerebilir. Her istek için tüm dosyaları ayrıştırmak ve birleştirmek yerine, Symfony kendi önbellek sistemini kullanır. Aslında, uygulama yapılandırması yalnızca ilk istek için ayrıştırılır ve daha sonra var/cache/ dizininde saklanan düz PHP koduna derlenir.

Geliştirme ortamında, Symfony siz bir dosyayı değiştirirken önbelleği güncelleyecek kadar akıllıdır. Ancak, prod ortamında işleri hızlandırmak için kodunuzu güncellerken veya yapılandırmasını değiştirirken önbelleği temizleme sorumluluğu size aittir. Prod ortamında önbelleği temizlemek için aşağıdaki komutu çalıştırabilirsiniz:

php bin/console cache:clear --env=prod

Bir web uygulaması geliştirirken, bir çok yönden işler hatalı gidebilir. var/logs/ dizininde bulunan günlük dosyaları size isteklerle ilgili her şeyi anlatır ve problemi çabucak düzeltmenize yardımcı olur.

Komut satırı arabirimi kullanımı

Her uygulama, uygulamanıza işlem yapmanıza yardımcı olan bir komut satırı arabirimi aracı (bin/console) ile birlikte gelir. Sıkıcı ve tekrar eden görevleri otomatikleştirerek verimliliğinizi artıran komutlar sunar.

Yetenekleri hakkında daha fazla bilgi edinmek için herhangi bir argüman olmadan çalıştırın:

php bin/console

--help seçeneği, komutun kullanımı hakkında bilgi sahibi olmanızı sağlar:

php bin/console debug:router --help