You are currently reading the 1.2 documentation. Switch to 2.2  2.1  2.0 

Existing Databases

A common case when looking for ORM tools like Doctrine is that the database and the code that access it is growing large/complex. A more substantial tool is needed than manual SQL code.

Doctrine has support for generating Doctrine_Record classes from your existing database. There is no need for you to manually write all the Doctrine_Record classes for your domain model.

Making the first import

Let's consider we have a mysql database called doctrine_test with a single table named user. The user table has been created with the following sql statement:

CREATE TABLE user (
   id bigint(20) NOT NULL auto_increment,
   first_name varchar(255) default NULL,
   last_name varchar(255) default NULL,
   username varchar(255) default NULL,
   password varchar(255) default NULL,
   type varchar(255) default NULL,
   is_active tinyint(1) default '1',
   is_super_admin tinyint(1) default '0',
   created_at TIMESTAMP,
   updated_at TIMESTAMP,
   PRIMARY KEY  (id)
) ENGINE=InnoDB

Now we would like to convert it into Doctrine_Record class. With Doctrine this is easy! Remember our test script we created in the Getting Started chapter? We're going to use that generate our models.

First we need to modify our bootstrap.php to use the MySQL database instead of sqlite memory:

// bootstrap.php

// ...
$conn = Doctrine_Manager::connection('mysql://root:mys3cr3et@localhost/doctrine_test', 'doctrine');
// ...

You can use the $conn->createDatabase() method to create the database if it does not already exist and the connected user has permission to create databases. Then use the above provided CREATE TABLE statement to create the table.

Now we need a place to store our generated classes so lets create a directory named models in the doctrine_test directory:

$ mkdir doctrine_test/models

Now we just need to add the code to our test.php script to generate the model classes:

// test.php

// ...
Doctrine_Core::generateModelsFromDb('models', array('doctrine'), array('generateTableClasses' => true));

The generateModelsFromDb method only requires one parameter and it is the import directory (the directory where the generated record files will be written to). The second argument is an array of database connection names to generate models for, and the third is the array of options to use for the model building.

That's it! Now there should be a file called BaseUser.php in your doctrine_test/models/generated directory. The file should look like the following:

// models/generated/BaseUser.php

/**
 * This class has been auto-generated by the Doctrine ORM Framework
 */
abstract class BaseUser extends Doctrine_Record
{
  public function setTableDefinition()
  {
    $this->setTableName('user');
    $this->hasColumn('id', 'integer', 8, array('type' => 'integer', 'length' => 8, 'primary' => true, 'autoincrement' => true));
    $this->hasColumn('first_name', 'string', 255, array('type' => 'string', 'length' => 255));
    $this->hasColumn('last_name', 'string', 255, array('type' => 'string', 'length' => 255));
    $this->hasColumn('username', 'string', 255, array('type' => 'string', 'length' => 255));
    $this->hasColumn('password', 'string', 255, array('type' => 'string', 'length' => 255));
    $this->hasColumn('type', 'string', 255, array('type' => 'string', 'length' => 255));
    $this->hasColumn('is_active', 'integer', 1, array('type' => 'integer', 'length' => 1, 'default' => '1'));
    $this->hasColumn('is_super_admin', 'integer', 1, array('type' => 'integer', 'length' => 1, 'default' => '0'));
    $this->hasColumn('created_at', 'timestamp', null, array('type' => 'timestamp', 'notnull' => true));
    $this->hasColumn('updated_at', 'timestamp', null, array('type' => 'timestamp', 'notnull' => true));
  }
}

You should also have a file called User.php in your doctrine_test/models directory. The file should look like the following:

// models/User.php

/**
 * This class has been auto-generated by the Doctrine ORM Framework
 */
class User extends BaseUser
{

}

Doctrine will automatically generate a skeleton Doctrine_Table class for the model at doctrine_test/models/UserTable.php because we passed the option generateTableClasses with a value of true. The file should look like the following:

// models/UserTable.php

/**
 * This class has been auto-generated by the Doctrine ORM Framework
 */
class UserTable extends Doctrine_Table
{

}

You can place custom functions inside the User and UserTable classes to customize the functionality of your models. Below are some examples:

// models/User.php

// ...
class User extends BaseUser
{
    public function setPassword($password)
    {
        return $this->_set('password', md5($password));
    }
}

In order for the above password accessor overriding to work properly you must enabled the auto_accessor_override attribute in your bootstrap.php file like done below.

// bootstrap.php

// ...
$manager->setAttribute(Doctrine_Core::ATTR_AUTO_ACCESSOR_OVERRIDE, true);

Now when you try and set a users password it will be md5 encrypted. First we need to modify our bootstrap.php file to include some code for autoloading our models from the models directory:

// bootstrap.php

// ...
Doctrine_Core::loadModels('models');

The model loading is fully explained later in the Autoloading Models section of this chapter.

Now we can modify test.php to include some code which will test the changes we made to the User model:

// test.php

// ...

$user = new User();
$user->username = 'jwage';
$user->password = 'changeme';

echo $user->password; // outputs md5 hash and not changeme

Now when you execute test.php from your terminal you should see the following:

$ php test.php
4cb9c8a8048fd02294477fcb1a41191a

Here is an example of some custom functions you might add to the UserTable class:

// models/UserTable.php

// ...
class UserTable extends Doctrine_Table
{
    public function getCreatedToday()
    {
        $today = date('Y-m-d h:i:s', strtotime(date('Y-m-d')));
        return $this->createQuery('u')
            ->where('u.created_at > ?', $today)
            ->execute();
    }
}

In order for custom Doctrine_Table classes to be loaded you must enable the autoload_table_classes attribute in your bootstrap.php file like done below.

// boostrap.php

// ...
$manager->setAttribute(Doctrine_Core::ATTR_AUTOLOAD_TABLE_CLASSES, true);

Now you have access to this function when you are working with the UserTable instance:

// test.php

// ...
$usersCreatedToday = Doctrine_Core::getTable('User')->getCreatedToday();

Questions and Feedback

If you find a problem with the documentation or have a suggestion, please register and open a ticket.

If you need support or have a technical question, you can post to the user mailing-list.