PHP yazanlar için en iyi framework ve en iyi ORM yi entegre edelim.

Kaynak : http://www.oelerich.org/?p=315

Zend Framework ün kurulu olduğunu varsayarak anlatacağım.

Efendim ilk olarak http://www.doctrine-project.org/projects/orm/download adresinden stabil olan Doctrine 2.0 sürümünü indiriyoruz.Daha sonrasında Doctrine dizinini Zend de bulunana library dizini altına koyuyoruz. bin dizinini ise zf nin root dizinine koyuyoruz.

application.ini dosyamızda Doctrine entegrasyonunuda kullanacağımız konfigürasyonları belirtiyoruz.

doctrine.conn.host = '127.0.0.1'
doctrine.conn.user = 'root'
doctrine.conn.pass = root''
doctrine.conn.driv = 'pdo_mysql'
doctrine.conn.dbname = 'zf-test'
doctrine.path.models = APPLICATION_PATH "/models"

Bu ayarlamayı yaptıktan sonra Bootstrap dosyasında belli değişiklikler yapıyoruz. Doctrine kütüphanelerini Bootstrap.php dosyasında yüklüyoruz.Örnek kod aşağıdaki gibidir.

<?php

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    /**
     * generate registry
     * @return Zend_Registry
     */
    protected function _initRegistry(){
        $registry = Zend_Registry::getInstance();
        return $registry;
    }

    /**
     * Register namespace Default_
     * @return Zend_Application_Module_Autoloader
     */
    protected function _initAutoload()
    {
        $autoloader = new Zend_Application_Module_Autoloader(array(
            'namespace' => 'Default_',
            'basePath'  => dirname(__FILE__),
        ));
        return $autoloader;
    }

    /**
     * Initialize Doctrine
     * @return Doctrine_Manager
     */
    public function _initDoctrine() {
        // include and register Doctrine's class loader
        require_once('Doctrine/Common/ClassLoader.php');
        $classLoader = new \Doctrine\Common\ClassLoader(
            'Doctrine',
            APPLICATION_PATH . '/../library/'
        );
        $classLoader->register();

        // create the Doctrine configuration
        $config = new \Doctrine\ORM\Configuration();

        // setting the cache ( to ArrayCache. Take a look at
        // the Doctrine manual for different options ! )
        $cache = new \Doctrine\Common\Cache\ArrayCache;
        $config->setMetadataCacheImpl($cache);
        $config->setQueryCacheImpl($cache);

        // choosing the driver for our database schema
        // we'll use annotations
        $driver = $config->newDefaultAnnotationDriver(
            APPLICATION_PATH . '/models'
        );
        $config->setMetadataDriverImpl($driver);

        // set the proxy dir and set some options
        $config->setProxyDir(APPLICATION_PATH . '/models/Proxies');
        $config->setAutoGenerateProxyClasses(true);
        $config->setProxyNamespace('App\Proxies');

        // now create the entity manager and use the connection
        // settings we defined in our application.ini
        $connectionSettings = $this->getOption('doctrine');
        $conn = array(
            'driver'    => $connectionSettings['conn']['driv'],
            'user'      => $connectionSettings['conn']['user'],
            'password'  => $connectionSettings['conn']['pass'],
            'dbname'    => $connectionSettings['conn']['dbname'],
            'host'      => $connectionSettings['conn']['host']
        );
        $entityManager = \Doctrine\ORM\EntityManager::create($conn, $config);

        // push the entity manager into our registry for later use
        $registry = Zend_Registry::getInstance();
        $registry->entitymanager = $entityManager;

        return $entityManager;
    }

}


İlk iki metod Doctrine ile ilgili bir işlem yapmıyor. Sadece Zend in Autoloader ve Registry modüllerini oluşturuyor. _initDoctrine metodunda ise gerekli belirtilen konfigürasyonlara göre Doctrine nesnesini oluşturuyoruz.Doctrine e bağlı olarak ArrayCache Proxy ve EntitiyManager oluşturuluyor.Bunları tam olarak incelemediğim için pek yorum yapamıyorum.Kaynakta belirtilen ise ArrayCache performansı daha üst seviyede tutabilmek için Doctrine in cache mekanizması, Proxy sanırım o da incelememiş :) , EntityManager veritabanı ve bizim modellerimiz arasındaki bir interface.Daha detaylı incelediğimde umarım bu konu hakkında da bir yazı yazabilirim :)

Sonrasında bir model yeni adıyla bir entity oluşturuyoruz.

<?php

/**
 * @Entity
 * @Table(name="test123")
 */
class Default_Model_Test
{
    /**
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;

    /** @Column(type="string") */
    private $name;

    public function setName($string) {
        $this->name = $string;
        return true;
    }
}

Doctrine 2 ile gelen yeni bir olay ise model oluşturma veya modelden DB oluşturma işlerini bin adlı dizinden yapabiliyor olmanız.Kaynakta söylendiği gibi bin/doctrine.php dosyasını aşağıdaki şekilde değiştirdim.

<?php

define('APPLICATION_ENV', 'development');

define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));

set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path(),
)));

// Doctrine and Symfony Classes
require_once 'Doctrine/Common/ClassLoader.php';
$classLoader = new \Doctrine\Common\ClassLoader('Doctrine', APPLICATION_PATH . '/../library');
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Symfony', APPLICATION_PATH . '/../library/Doctrine');
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Entities', APPLICATION_PATH . '/models');
$classLoader->setNamespaceSeparator('_');
$classLoader->register();

// Zend Components
require_once 'Zend/Application.php';

// Create application
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/application.ini'
);

// bootstrap doctrine
$application->getBootstrap()->bootstrap('doctrine');
$em = $application->getBootstrap()->getResource('doctrine');

// generate the Doctrine HelperSet
$helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
    'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
    'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
));

\Doctrine\ORM\Tools\Console\ConsoleRunner::run($helperSet);

Sonrasında oluşturduğum bin dizinine giderek doctrine i executable yapıyorum.

chmod +x ./doctrine

Şu şekilde de modelden veritabanını oluşturuyorum.Pardon entitiy den :)

./doctrine orm:schema-tool:create

Kullanımı da şu şekilde oluyor :

<?php

class IndexController extends Zend_Controller_Action
{
    public function init()
    {
        $registry = Zend_Registry::getInstance();
        $this->_em = $registry->entitymanager;
    }

    public function indexAction()
    {
        $testEntity = new Default_Model_Test;
        $testEntity->setName('Zaphod Beeblebrox');
        $this->_em->persist($testEntity);
        $this->_em->flush();
    }

}

Fakat siz de benim gibi ters bir adamsanız şöyle birşeye ihtiyaç duyacaksınız.”İşte efendim ben DB yi oluşturayım entitiyler buna göre oluşsun” der iseniz eğer şunu yapıyoruz.

./doctrine orm:convert-mapping --from-database php /tmp/
Böylece /tmp dizinine tablolarınızın php çıktısını alabilirsiniz.Aynı şekilde ph p yerine yaml ve xml de alabiliyorsunuz.Bunun için php yerine xml veya yaml yazmanız yeterli.
İyi gönler efendim… :)