ZF2

Zend Framework 2’yi tanıyalım…

Bildiğiniz üzere Zend Framework 2’nin kararlı sürümü geçtiğimiz günlerde yayınlandı. Zend ciddi değişiklikler ile karşımıza neredeyse tamamen yeni bir ürün çıkarttı. Alışması süresi okuma hızınıza bağlı olarak değişiklik gösterecektir. Biz bu açığı kapatmak için bu yazıyı hazırladık… ZF1’in problemleri Öğrenme güçlüğü Performans Bileşenler arasındaki tutarsızlık ZF2’nin artıları Öğrenmesi kolay Kolay uzantılar Daha iyi bir performans […]

Bildiğiniz üzere Zend Framework 2’nin kararlı sürümü geçtiğimiz günlerde yayınlandı.
Zend ciddi değişiklikler ile karşımıza neredeyse tamamen yeni bir ürün çıkarttı.
Alışması süresi okuma hızınıza bağlı olarak değişiklik gösterecektir. Biz bu açığı kapatmak için bu yazıyı hazırladık…

ZF1’in problemleri

Öğrenme güçlüğü
Performans
Bileşenler arasındaki tutarsızlık

ZF2’nin artıları

Öğrenmesi kolay
Kolay uzantılar
Daha iyi bir performans (ZF1’e göre %200 daha iyi)
Basitlik
PHP 5.3 desteği ile daha gelişmiş

Öncelikle projeyi oluşturmak için Zend Tool bulunmuyor. Henüz hazırlanmamış.
Direk ZendSkeletonApplication u indirerek projeyi indirebilirsiniz. Ama ben sizin için daha iyi bir paket hazırladım şurdan indirebilirsiniz. https://github.com/volkan/ZendSkeletonApplication

Öncesinde söylemem gereken “Bağımlılık yöneticisi olarak” composer kullanmanız gerektiği. Bununla işleriniz ciddi manada kolaylaşacak. Şöyleki;

$> git clone https://github.com/volkan/ZendSkeletonApplication
$> cd ZendSkeletonApplication
$> COMPOSER_PROCESS_TIMEOUT=5000 composer update

Ve herşey bitti…

zf2custom.local/contact yazarak (apache ayarlarını yaptığınızı varsayıyorum) direk hazır uygulamayı kullanmaya başlıyabilirsiniz.
içinde aynı zamanda ZF developer tool da bulunuyor. Proje indiğine göre şimdi klasör yapısını inceleyelim.

── ZendSkeletonApplicationCustom
│   ├── LICENSE.txt
│   ├── README.md
│   ├── composer.json -> kurulumunu istediğimiz paketler
│   ├── composer.json.orig
│   ├── composer.lock
│   ├── composer.phar
│   ├── config -> modül yönetimi, globalleştirme ve özelleştirmeler
│   │   ├── application.config.php -> her modülün adını mutlaka yazacağınız dosya
│   │   └── autoload modüle özel veya global ayarları yazacağınız dosya
│   ├── data
│   │   └── cache
│   ├── init_autoloader.php
│   ├── module -> modüllerin bulunacağı klasör
│   │   └── Application
│   ├── public
│   │   ├── css
│   │   ├── images
│   │   ├── index.php
│   │   └── js
│   └── vendor -> modüllerin ve kütüphanelerin bulunacağı klasör
│   ├── README.md
│   ├── ZF2
│   ├── autoload.php
│   ├── bjyoungblood
│   ├── composer
│   ├── doctrine
│   ├── phly
│   ├── zendframework
│   └── zf-commons

Modülün detayına bakalım:

├── phly-contact
│   ├── Module.php -> temel ayarlar ve autoloader biçiminin barındığı yer
│   ├── README.md
│   ├── TODO.md
│   ├── autoload_classmap.php
│   ├── autoload_function.php
│   ├── autoload_register.php
│   ├── composer.json
│   ├── config
│   │   ├── module.config.php -> uygulamanın router, translater, controller, view_manager gibi temel ayarları içinde barındırır.
│   │   └── module.phly-contact.local.php -> ZendSkeletonApplicationCustom/config/autoload altına kopyalanacak dosya
│   ├── src
│   │   └── PhlyContact
│   │   ├── Controller
│   │   ├── Form
│   │   └── Service
│   └── view
│   └── phly-contact
│   └── contact

src ise bildiğiniz standart yapı. PSR-O standart yapısı kullanılmaktadır.

Modüllerin özelliği:
Modüller aslında namespace olarak düşünülebilir.
Bir modül içinde herşeyi barındırır
Bütün modüller çalışma esnasında  merge edilir.
Ana modül (default) module/Application dur.  Onun configinden router yönlendirmesi ile
bunu değiştirebilirsiniz.
Herhangi bir modülden router da bir ana kategorinin altına yeni bir yönlendirme tanımlayabilirsiniz.
Her modül kendi autoloaderını içinde barındırabiliyor.

Gördüğünüz üzere oldukça basit. Sadece Biraz DI olaylarını anlamak gerek. Onun içinde şurası ideal.

ZF2’y idaha iyi anlamak için Doctrine 2 ile kullanım örneği yapacağız. Bunun için yukarda indirdiğiniz projede herşey mevcut. Ama dilerseniz öncesinde birkaç ip ucu ile başlayalım.

Yeni Zend de actionların dönüş değerleri mevcut. Dönüş tipini json, html, vs.. belirtebiliyorsunuz. Boş ” değerde döndürebilirsiniz. O zaman action’ın defaul olarak çalştıracağı html dosyası kullanılmaz.

$jsonModel = new JsonModel();
$viewModel = new ViewModel();
return '';

Eğer projenize yazdığınız başka kütüphaneler eklemek istiyorsanız direk yazmak yerine

new YeniNesne();

service_manager nesnesini kullanarak parametrelerini gönderip çalıştırabilirsiniz. Bunun için Module.php dosyasına aşağıdaki metodu ekleyebilirsiniz.

    public function getServiceConfig()
    {
        return array(
            'factories' => array(
                'albumTable' =>  function($sm) {
                    $table = $sm->get('doctrine.entitymanager.orm_default')->getRepository('Application\Entity\Album');
                    return $table;
                },
            ),
        );
    }

Veya module.config.php dosyası içine ekleyebilirsiniz.

    'service_manager' => array(
        'factories' => array(
            'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
            'albumTable' =>  function($sm) {
                $table = $sm->get('doctrine.entitymanager.orm_default')->getRepository('Application\Entity\Album');
                return $table;
            },
        ),
    ),

Herhangi bir contoller içerisindeki bir metodu yüklenme sırasında ilk olarak çalıştırabilirsiniz. Controller içerisinde setEntityManager(EntityManager $e) isimli bir metod olduğunu varsayalım. Controller yüklenirken ilk bu metodu çalıştırmak için şöyle bir yol izleyebiliriz.

Module.php içerisine aşağıdaki kodu ekliyoruz

    public function init(ModuleManager $moduleManager)
    {
        $sharedEvents = $moduleManager->getEventManager()->getSharedManager();
        $sharedEvents->attach(__NAMESPACE__, 'dispatch', function($e) {
            $application = $e->getApplication();
            $serviceManager = $application->getServiceManager();
            $controller = $e->getTarget();
            $controller->setEntityManager($serviceManager->get('doctrine.entitymanager.orm_default'));
        }, 100);
    }

Bu komut ile her controller içerisinde bu setEntityManager metoduna erişip çalıştırılmaktadır. O yüzden bu metod var olmalı yoksa hata alırsınız.

Şimdi Doctrine 2 bağlantılarını yapalım.
Önce mevcut db’yi kullanarak yapıyı kuralım. (metadata)

vendor/bin/doctrine-module orm:convert-mapping --namespace="Application\Entity\\" --from-database  annotation ./module/Application/src/

Şimdi entities

vendor/bin/doctrine-module orm:generate-entities ./module/Application/src/

Şimdi proxie olaylarını oluşturalım.

vendor/bin/doctrine-module orm:generate-proxies

Bu yapıyı kurduktan sonra Repository leri oluturalım. Burasının oluşması için Entity içine girip her tablonun Repository yolunu belirtmek gerek.
Application/Entity/

* @ORM\Entity(repositoryClass="Application\Repository\AlbumRepository")

Sonrasında çalıştıracağımız komut:

vendor/bin/doctrine-module orm:generate-repositories ./module/Application/src/

Şimdi işlemler tamam artık Controller üzerinden DB ye erişip çalışabiliriz.Yukarda service_manager için yaptığımız eklemeleri kullanabiliriz. Aynı zamanda IDE nin otomatik tamamlama özelliğini kullanmak için şöyle yapabiliriz;

    /**
     * @return \Application\Repository\AlbumRepository
     */
    public function getAlbumTable()
    {
        static $table;

        if (null === $table) {
            $table = $this->getServiceLocator()->get('albumTable');
        }
        return $table;
    }

İpuçları
Post, Get, Header vs.. alabilmek için kullanacağınız yöntem;

$this->params()->fromPost('parametre');
$this->params()->fromQuery('parametre');
$this->params()->fromRoute('parametre');
$this->params()->fromHeader('parametre');
$this->params()->fromFiles('parametre');

Özetle çok güzel olmuş. Sorularınızı bu başlık altında yanıtlamaya çalışacağım. Soru sormakten çekinmeyin lütfen.

Kaynaklar:

http://akrabat.com/wp-content/uploads/PHPBNL11-ZF2-Whats-New.pdf
http://akrabat.com/zend-framework-2/overriding-module-configuration-in-zf2/
http://mwop.net/slides/2012-06-07-Zf2-Module-Workshop/Zf2ModuleWorkshop.html
http://blog.evan.pro
http://ocramius.github.com/blog/zend-framework-2-controllers-and-dependency-injection-with-zend-di/