Quite often I find myself overwhelmed by the amount of news I try to consume on a daily basis. Often the result, unfortunately, is that my brain shuts down to some extent and I find it hard to prioritize the things I really want to investigate. For example, ever since the January 2008 edition of PHP | Architect, in which there was an article about The Doctrine Framework, I have been trying to find the time to dig in. On the way into work today I made the decision that, on a weekly basis, I would begin investigating things that interest me. This week of course is devoted to Doctrine.

Introduction

What is Doctrine? According to the website:

Doctrine is a PHP ORM (object relational mapper) for PHP 5.2.3+ that sits on top of a powerful PHP DBAL (database abstraction layer). One of its key features is the ability to optionally write database queries in an OO (object oriented) SQL-dialect called DQL inspired by Hibernates HQL. This provides developers with a powerful alternative to SQL that maintains a maximum of flexibility without requiring needless code duplication.

Ok, sounds good to me. Let’s get started.

Monday Night

Slowly I’m moving my home dev environment over to Linux. So, I’ve spent a good chunk of time tonight getting AMP/Subversion/etc setup. Once I had my dev environment setup for Doctrine (which was nothing more than setting up a VirtualHost entry for my project directory under LAMP), I used the PEAR option (one of 4 options) for installing the application. Here is where I ran into my first issue:

Invalid or missing remote package file
Package “http://pear.phpdoctrine.org/Doctrine-0.10.2″ is not valid
install failed

I didn’t dwell on this for too long though. My next step was to try installation via Subversion. Piece of Cake. I modified the svn checkout slightly to checkout branch .11 instead of .10, and I also specified that I wanted to checkout the branch to my working application directory. So, to be clear my checkout looked like:

svn co http://svn.phpdoctrine.org/branches/0.11 .

I really didn’t get into Doctrine tonight, however I am setup and ready to go for tomorrow night.

Tuesday Night

My next step for tonight will be the section labeled “working with existing tables“. To prepare for this section I created a database called doctrine, and I imported the sql for the “files” table they provide in the section. The first thing the article tells me to do is create a file to convert my table into a record class, however it doesn’t tell me where I should put this class. I decided to create a script called build_rc.php, and I placed it in my app root. I also needed to create a myrecords directory to remain consistant with the tutorial. Running my script exposed permission issues on the myrecords directory, however changing permissions to 777 on that directory took care of the issue. After running the script, a BaseFile was generated, as was a BaseFile extended class called File. The tutorial mentions that a third class should be generated which extends Doctrine_Table, however this class nowhere to be found. I went through the steps a few times before I finally just created the class myself.

Next, I completed the section creating tables. The section worked exactly as advertised and allowed me to export the record classes into my database. Nice little feature. Essentially, Doctrine provides a means by which you can have the application create your tables on the fly. Doctrine makes is very easy to define relationships between models, and to specify relationship constraints/cascades. For example:

// file User.php
class User extends Doctrine_Record
{
   public function setTableDefinition()
   {
      $this->hasColumn('name', 'string', 20);
   }

   public function setUp()
   {
      $this->hasMany('Phonenumber', array('local' => 'id',
      'foreign' => 'user_id'));
   }
}

// file Phonenumber.php
class Phonenumber extends Doctrine_Record
{
   public function setTableDefinition()
   {
      $this->hasColumn('phonenumber', 'string', 20);
      $this->hasColumn('user_id', 'integer');
   }

   public function setUp()
   {
      $this->hasOne('User', array('local' => 'user_id',
      'foreign' => 'id', 'onDelete' => 'CASCADE'));
   }
}

Loading the models above and executing the createTablesFromModels method will of course create the tables.

Doctrine::createTablesFromModels('models');

It is also possible to generate the sql to create the tables, for use in a text file, etc. For example:


require_once('lib/Doctrine.php');
spl_autoload_register(array('Doctrine', 'autoload'));//in order to export we need a database connection
Doctrine_Manager::connection('mysql://user:pw@localhost/doctrine');
$queries = Doctrine::generateSqlFromModels('models');
echo $queries;

Will generate and dispaly the sql as such:

CREATE TABLE phonenumber (id BIGINT AUTO_INCREMENT,
   phonenumber VARCHAR(20),
   user_id BIGINT,
   INDEX user_id_idx (user_id),
   PRIMARY KEY(id)) ENGINE = INNODB;

CREATE TABLE user (id BIGINT AUTO_INCREMENT,
   name VARCHAR(20),
   PRIMARY KEY(id)) ENGINE = INNODB;

ALTER TABLE phonenumber ADD FOREIGN KEY (user_id)
   REFERENCES user(id) ON DELETE CASCADE;

This is pretty cool stuff. Notice by default the sql selects INNODB as the engine. I need to refresh my memory regarding the differences between INNODB and MYISAM. I seem to recall a PHPArchitect Podcast on this very topic. I’ll have to take a look back in time.

Wednesday Night

Ok, so I’ve decided that by completing every little section and writing about it I’m really just wasting time that I could be programming. So, instead, I’m going to take a close look at the table of contents and see what interests me. From there I’ll give it a try and write about the results here …

And I didn’t do a single thing tonight.  Someone is trying to rip off my wife and I through my PayPal account, and it’s wasting my Doctrine time.

In Conclusion

I ran out of time. I had friends come into town for the holiday and my week in Doctrine didn’t turn out as I had hoped. I’m disappointed because I really wanted to dig into some of Doctrine’s more interesting features. Anyway, this is really a piece of crap blog post. It does nothing at all to convey how impressed I am with what Doctrine has to offer. So, what does Doctrine have to offer? A super DBAL which supports a powerful ORM. But I’m not telling you anything you couldn’t have read by reading the introduction paragraph on the first page of the site. In the future, if the right project comes along I will definitely be giving this piece of software a second look. If I do one day decide to write an application in Doctrine, I’ll be sure to write a bit about it here.