Page 1 of 1

[Zend] Integration with Doctrine

Posted: Mon Nov 01, 2010 9:06 am
by VladSun
What's the best way to integrate Doctrine DBAL/ORM into a Zend project? Autloaders, Doctrine Model autoloaders, etc.
I've been googling a while but I can't find a good enough example for it.

Re: [Zend] Integration with Doctrine

Posted: Tue Nov 02, 2010 3:40 am
by Zyxist
Which version of Doctrine do you mean? For Doctrine 1.1, the integration is quite simple, if you solve the autoloading issue. Unfortunately, I can't help you with it, because I use neither Zend nor Doctrine autoloader, but my own universal one, from my library collection. Basically, there are two problems to solve:

1. Loading the Doctrine itself: it can be done by configuring the autoloader to load Doctrine-prefixed classes from the Doctrine directory and should be allowed in most of the autoloaders.
2. Loading Doctrine models: here, I wrote a custom autoloader registered after the default one which interpreted all the other class loading requests as models.

Once this is done, the rest is very simple: just configure Doctrine in the standard way and start using it. You can do this either by Zend_Application, or manually. I chose the second way, because I started my project quite a long ago, when Zend_Application simply did not exist yet :).

One more thing that you will probably find useful is the session handler that uses Doctrine. Here you can get one from my tutorial about Doctrine integration (unfortunately, available in Polish only). Feel free to use it:

Code: Select all

<?php
 /**
 * @author Tomasz Jędrzejewski
 */
class Vendor_Doctrine_SessionHandler implements Zend_Session_SaveHandler_Interface
{
	private $_sessionName;
	private $_session;
	private $_lifetime;
 
	public function __construct($lifetime = null)
	{
		if(is_null($lifetime))
		{
			$this->_lifetime = (int) ini_get('session.gc_maxlifetime');
		}
		else
		{
			$this->_lifetime = (int) $lifetime;
		}
	} // end __construct();
 
	public function setLifetime($lifetime)
	{
		$this->_lifetime = $lifetime;
	} // end setLifetime();
 
	public function getLifetime()
	{
		return $this->_lifetime;
	} // end getLifetime();
 
	public function read($id)
		{
		$this->_session = Doctrine::getTable('Session')->find($id);

		if(empty($this->_session))
		{
			$this->_session = new Session();
			$this->_session->id = $id;
			$this->_session->lifetime = $this->_lifetime;

			return '';
		}
		return $this->_session->data;
	} // end read();
 
	public function write($id, $data)
	{
		$this->_session->data = $data;
		$this->_session->modified = time();
		$this->_session->save();

		return true;
	} // end write();
 
	public function destroy($id)
	{
		if($this->_session->id == $id)
		{
			$this->_session->delete();
			return true;
		}
		return false;
	} // end destroy();
 
	public function gc($maxlifetime)
	{
		Doctrine_Query::create()->delete('Session s')->where('s.modified < (? - s.lifetime)', time())->execute();
	} // end gc();
 
	public function open($save_path, $name)
	{
		$this->_sessionName = $name;
		return true;
	} // end open();

	public function close()
	{
		return true;
	} // end close();
} // end Vendor_Doctrine_SessionHandler;
Registration:

Code: Select all

Zend_Session::setSaveHandler(new Vendor_Doctrine_SessionHandler());
Zend_Session::start();
And the model in YAML:

Code: Select all

Session:
    tableName: session
    columns:
        id:
            type: string(32)
            primary: true
        modified: integer(4)
        lifetime: integer(4)
        data: clob
With Doctrine 2, things look a bit different (you need a namespace support, but configuring autoloaders is much easier). Hopefully, Zend Framework developers decided to abandon their own ORM and use Doctrine, so in the future it should be available out-of-the-box.

Re: [Zend] Integration with Doctrine

Posted: Fri Nov 05, 2010 11:41 am
by josh
With Zend you just set Zend_Loader to be the autoloader. You add prefixes and paths. So you say look in /lib/Doc/ for classes beginning with Doc_ and it will.

You can 'integrate' any framework into zend by including it, disabling it's own build in auto loading, and then subsequently adding it's class prefix to Zend's auto loader.

Alternatively enable 'fallback auto loading' and it will auto load anything on all include paths. Just set your include path and it takes care of the rest.