Skip to content

Using Doctrine with Code Igniter

World Wide Web Server edited this page Jul 4, 2012 · 19 revisions

Category:Core::Integration | Category:Core::Database [h3]Learning about Doctrine[/h3]

The best way to learn about Doctrine is to read about it in the manual. Here are some important links.

[url=http://www.phpdoctrine.org/documentation/manual/0_11]Doctrine 0.11 Manual[/url] [url=http://www.phpdoctrine.org/documentation/api/0_11]Doctrine 0.11 API Docs[/url]

[h3]Download Doctrine[/h3]

First we must get the source of Doctrine from svn and place it in the system/database folder.

[code] $ cd system/database $ svn co http://svn.phpdoctrine.org/branches/0.11/lib doctrine $ cd ..

// If you use svn in your project you can set Doctrine // as an external so you receive bug fixes automatically from svn $ svn propedit svn:externals database

// In your favorite editor add the following line // doctrine http://svn.phpdoctrine.org/branches/0.11/lib [/code]

[h3]Setup Doctrine[/h3]

Now we must setup the configuration for Doctrine and load it in system/application/config/database.php

[code] $ vi application/config/database.php [/code]

The code below needs to be added under this line of code

[code] $db['default']['cachedir'] = ""; [/code]

Add this code [code] // Create dsn from the info above $db['default']['dsn'] = $db['default']['dbdriver'] . '://' . $db['default']['username'] . ':' . $db['default']['password']. '@' . $db['default']['hostname'] . '/' . $db['default']['database'];

// Require Doctrine.php require_once(realpath(dirname(FILE) . '/../..') . DIRECTORY_SEPARATOR . 'database/doctrine/Doctrine.php');

// Set the autoloader spl_autoload_register(array('Doctrine', 'autoload'));

// Load the Doctrine connection Doctrine_Manager::connection($db['default']['dsn'], $db['default']['database']);

// Set the model loading to conservative/lazy loading Doctrine_Manager::getInstance()->setAttribute('model_loading', 'conservative');

// Load the models for the autoloader Doctrine::loadModels(realpath(dirname(FILE) . '/..') . DIRECTORY_SEPARATOR . 'models'); [/code]

Now we must make sure system/application/config/database.php is included in your front controller. Open your front controller in your favorite text editor.

[code] $ cd .. $ vi index.php [/code]

Change the last 2 lines of code of index.php with the following

[code] require_once APPPATH.'config/database.php'; require_once BASEPATH.'codeigniter/CodeIgniter'.EXT; ?> [/code]

[h3]Setup Command Line Interface[/h3]

Create the following file: system/application/doctrine and chmod the file so it can be executed. Place the code below in to the doctrine file.

[code] $ vi system/application/doctrine [/code]

Place this code in system/application/doctrine

[code] #!/usr/bin/env php <?php define('BASEPATH','.'); // mockup that this app was executed from ci ;) chdir(dirname(FILE)); include('doctrine.php'); [/code]

Now create the following file: system/application/doctrine.php. Place the code below in to the doctrine.php file.

[code] <?php require_once('config/database.php');

// Configure Doctrine Cli // Normally these are arguments to the cli tasks but if they are set here the arguments will be auto-filled $config = array('data_fixtures_path' => dirname(FILE) . DIRECTORY_SEPARATOR . '/fixtures', 'models_path' => dirname(FILE) . DIRECTORY_SEPARATOR . '/models', 'migrations_path' => dirname(FILE) . DIRECTORY_SEPARATOR . '/migrations', 'sql_path' => dirname(FILE) . DIRECTORY_SEPARATOR . '/sql', 'yaml_schema_path' => dirname(FILE) . DIRECTORY_SEPARATOR . '/schema');

$cli = new Doctrine_Cli($config); $cli->run($_SERVER['argv']); [/code]

Now we must create all the directories for Doctrine to use

[code] // Create directory for your yaml data fixtures files $ mkdir system/application/fixtures

// Create directory for your migration classes $ mkdir system/application/migrations

// Create directory for your yaml schema files $ mkdir system/application/schema

// Create directory to generate your sql to create the database in $ mkdir system/application/sql [/code]

Now you have a command line interface ready to go. If you execute the doctrine shell script with no argument you will get a list of available commands

[code] $ cd system/application $ ./doctrine Doctrine Command Line Interface

./doctrine build-all ./doctrine build-all-load ./doctrine build-all-reload ./doctrine compile ./doctrine create-db ./doctrine create-tables ./doctrine dql ./doctrine drop-db ./doctrine dump-data ./doctrine generate-migration ./doctrine generate-migrations-db ./doctrine generate-migrations-models ./doctrine generate-models-db ./doctrine generate-models-yaml ./doctrine generate-sql ./doctrine generate-yaml-db ./doctrine generate-yaml-models ./doctrine load-data ./doctrine load-dummy-data ./doctrine migrate ./doctrine rebuild-db $ [/code]

On Microsoft Windows, call the script via the PHP binary (because the script won't invoke it automatically: [code]> php.exe doctrine[/code]

[h3]Start Using Doctrine[/h3]

It is simple to start using Doctrine now. First we must create a yaml schema file. (save it at schema with filename like : user.yml) [code]

User: columns: id: primary: true autoincrement: true type: integer(4) username: string(255) password: string(255) relations: Groups: # Relation alias or class name class: Group # Class name. Optional if alias is the class name local: user_id # Local: User.id = UserGroup.user_id. Optional foreign: group_id # Foreign: Group.id = UserGroup.group_id. Optional refClass: UserGroup # xRefClass for relating Users to Groups foreignAlias: Users # Opposite relationship alias. Group hasMany Users

Group: tableName: groups columns: id: primary: true autoincrement: true type: integer(4) name: string(255)

UserGroup: columns: user_id: type: integer(4) primary: true group_id: type: integer(4) primary: true relations: User: local: user_id # Local key foreign: id # Foreign key onDelete: CASCADE # Database constraint Group: local: group_id foreign: id onDelete: CASCADE [/code]

Now if you run the following command it will generate your models in system/application/models

[code] $ ./doctrine generate-models-yaml generate-models-yaml - Generated models successfully from YAML schema [/code]

Now check the file system/application/models/generated/BaseUser.php. You will see a compclass definition like below.

[code] <?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', 4, array('primary' => true, 'autoincrement' => true)); $this->hasColumn('username', 'string', 255); $this->hasColumn('password', 'string', 255); }

public function setUp() { $this->hasMany('Group as Groups', array('refClass' => 'UserGroup', 'local' => 'user_id', 'foreign' => 'group_id'));

$this->hasMany('UserGroup', array('local' => 'id',
                                  'foreign' => 'user_id'));

}

}

// Add custom methods to system/application/models/User.php

<?php

/**

  • This class has been auto-generated by the Doctrine ORM Framework */ class User extends BaseUser { public function setPassword($password) { $this->password = md5($password); } }

/**

  • This class has been auto-generated by the Doctrine ORM Framework */ class UserTable extends Doctrine_Table { public function retrieveAll() { $query = new Doctrine_Query(); $query->from('User u'); $query->orderby('u.username ASC');

    return $query->execute(); } } [/code]

Now we can create some sample data to load in to our application(this step requires you have a valid database configured and ready to go. The build-all-reload task will drop and recreate the database, create tables, and load data fixtures

Create a file in system/application/fixtures/users.yml

[code] $ vi fixtures/users.yml [/code]

Add the following yaml to the file

[code]

User: jwage: username: jwage password: test [/code]

Now run the build-all-reload task to drop db, build models, recreate

[code] $ ./doctrine build-all-reload build-all-reload - Are you sure you wish to drop your databases? (y/n) y build-all-reload - Successfully dropped database named: "jwage_codeigniter" build-all-reload - Generated models successfully from YAML schema build-all-reload - Successfully created database named: "jwage_codeigniter" build-all-reload - Created tables successfully build-all-reload - Data was successfully loaded [/code]

Now we are ready to use Doctrine in our actual actions. Lets open our system/application/views/welcome_message.php and somewhere add the following code somewhere.

[code] $user = new User(); $user->username = 'zYne-'; $user->setPassword('password'); $user->save();

$userTable = Doctrine::getTable('User'); $user = $userTable->findOneByUsername('zYne-');

echo $user->username; // prints 'zYne-'

$users = $userTable->retrieveAll();

echo $users->count(); // echo '2'' foreach ($users as $user) { echo $user->username; } [/code]

Clone this wiki locally