
front and back-end web development, Leeds, UK
Richard's Blog - Design, coding and life in Japan
Doctrine 2 and why you should use it!
Submitted by Richard on Thu, 07/29/2010 - 15:23If any of you are used to Hibernate in the Java world you will know what I am talking about. But Doctrine 2 is almost exactly the same as Hibernate. I have seen many approaches to ORM's in different languages, evern though you are not going to get more sexier than Rails' ActiveRecord, I believe the approach taken by Doctrine 2, Hibernate and others such as SQL Alchemy is the correct one.
Why is it good!
I believe strongly that output in our code should be objects and not arrays oof data. In Doctrine 2 we have main model objects/entities or POPO(Plain Old PHP Object) - taken from POJO from Java for each of our table maps, this is where we outline the spec of our table. I will use examples using the entity method of controlling our mappings (I will mention this later).
Example: to make our class (POPO) a doctrine compatible Entity class all we need to do is add entity, id and column annotations.
/** @Entity */
class Car
{
/**
* @Id @Column(type="integer")
* @GeneratedValue
*/
private $id;
/** @Column */
private $maker;
/** @Column */
private $model;
}The column variable names will directly correspond with your column names as will the main class name. To have the name of your table different to that of the class you can do the following:
/** * @Entity * @Table(name="vehicle") */ class Car
To change the column name you do the similar
/** @Column(name="manufacturer") */ private $maker;
Controversially we use Java like getter and setter public methods to retrieve and set the data in our object:
public function setMaker($maker)
{
$this->maker = $maker;
}
public function getMaker()
{
return $this->maker;
}Bootstrap
Then should you have your bootstrap set up right you can then access and save/persist these objects through the 'Entity Manager'.
$car = new Car;
$car->setMaker('Toyota');
$em->persist($car);
$em->flush();My bootstrap file is as follows
require_once __DIR__ . '/../lib/Doctrine/Common/ClassLoader.php';
$classLoader = new \Doctrine\Common\ClassLoader('Doctrine', __DIR__ . '/../Lib');
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Symfony', __DIR__ . '/../Lib');
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Entities', __DIR__);
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Dao', __DIR__);
$classLoader->register();
$config = new \Doctrine\ORM\Configuration();
$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
$config->setProxyDir(__DIR__ . '/Proxies');
$config->setProxyNamespace('Proxies');
$driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__."/Entities"));
$config->setMetadataDriverImpl($driverImpl);
$connectionOptions = array(
'dbname' => 'mydbname',
'user' => 'user',
'password' => 'password',
'host' => 'localhost',
'driver' => 'pdo_mysql',
);
$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);Here we are just setting our namespaces, telling doctrine our settings, and then also telling doctrine that we want to use Entities to tell about our Database mappings.
Database Mappings
This is where we tell doctrine about our table names, column names, associations and the like. I prefer to write db mapping information in the classes themselves as I can see and edit all table mappings and class settings in the same file. This is the entities annotation driver. The alternatives are php coded mapping files, yaml and for all you Java retro's xml files. But you will find yourself writing/generating table information double as you need to set your private variables in the entity class anyway.
Data Access
Data is retrieved via the standard EntityRepository by default, as in the example below
$user = $em->getRepository('Entities\Car')->find($id);I will finish this off by talking later about repositories and relationships.
Tags:
Recent Blog Posts
- Testing controllers in Lithium 2nd Feb 12, 18:19
- Practical Internationalization in Lithium 31st Dec 11, 02:06
- Using OAuth in Lithium 30th Dec 11, 23:47
- How to add your own Tokens from CCK fields in Druapl 7 17th Jun 11, 04:49
- Weaving Lithium #li3 into a legacy PHP application incrementally 5th Oct 10, 11:54
I agree that Doctrine 2 is
I agree that Doctrine 2 is great, because I also enjoyed many concepts. However, I think it should be clearly pointed out that in order to use it, you need a good cache, like APC, because without it the library is extremely slow (due to annotations and DQL parser). It can be a problem on shared hostings.
Post new comment