On my previous post I have write about doctrine usage with Zend Framework. On this post, I will try to give sample usage of doctrine that contain:
- Installation
- Configuration
- Models & Schema File
- Migration
The easiest way to learn and start to use doctrine is use Doctrine Sandbox with completed by configuration and directory structure.
Installation
Doctrine use PHP 5.2.3+, and make sure your php version have support first. When I write this post, the current stable version of doctrine is 1.1.4 and can be downloaded here and for doctrine sandbox here. Doctrine library also provided by Doctrine Sandbox, so you don't need Doctrine Installer more. If you have download and extract Doctrine Sandbox then it will produce files and folders like this:
config.php data/ doctrine doctrine.php index.php lib/ migrations/ models/ schema/
Here explanation about files and folders above
- config.php
Contain configuration of Doctrine. Path from library, models, migration, schema files, and path for export or import data.
- data/
This folder contain fixtures and sql folders. fixtures folder is used to save file that will be used to import data from yaml file. sql folder is used to save export of database in sql file.
- doctrine
This is an execution file, that used as tools for doctrine.
- doctrine.php
This file will include on doctrine tools above.
- index.php
This just sample file.
- lib/
This folder contain library of doctrine. On this library also contain doctrine installer. I suggest to move all folders and files on it to php include_path, for on every project that use doctrine, you just use library from include path, and don't need to include the library on every project.
- migrations/
This folder will contain of migration classes that will used by doctrine to make a migration.
- models/
This folder will contain of models classes
- schema/
This folder will contain of schema files in yaml file.
Configuration
For installation, doctrine don't need configuration. This library can be included on every projects. But I prefer to move Doctrine library to PHP include_path. Configuration will need when use doctrine. On this sandbox, configuration will be found on config.php
<?php
// set path sandbox
define('SANDBOX_PATH', dirname(__FILE__));
// set path for doctrine library
define('DOCTRINE_PATH', SANDBOX_PATH . DIRECTORY_SEPARATOR . 'lib');
// set path for data fixtures. It intended to import data from yaml file
define('DATA_FIXTURES_PATH', SANDBOX_PATH . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'fixtures');
// set path for models
define('MODELS_PATH', SANDBOX_PATH . DIRECTORY_SEPARATOR . 'models');
// set path for migration
define('MIGRATIONS_PATH', SANDBOX_PATH . DIRECTORY_SEPARATOR . 'migrations');
// set path to save sql file export database from doctrine
define('SQL_PATH', SANDBOX_PATH . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'sql');
// set path to save schema file
define('YAML_SCHEMA_PATH', SANDBOX_PATH . DIRECTORY_SEPARATOR . 'schema');
// set database path (assumed to use sqlite)
define('DB_PATH', SANDBOX_PATH . DIRECTORY_SEPARATOR . 'sandbox.db');
// set DSN
define('DSN', 'sqlite:///' . DB_PATH);
// if use mysql, user password and database (doctrine, doctrine, doctrine)
// define('DSN', 'mysql://doctrine:doctrine@localhost/doctrine');
// if have move library to php include path, this require_once() can be ignored
require_once(DOCTRINE_PATH . DIRECTORY_SEPARATOR . 'Doctrine.php');
spl_autoload_register(array('Doctrine', 'autoload'));
// make database connection base on DSN
$manager = Doctrine_Manager::getInstance();
$manager->openConnection(DSN, 'doctrine');
$manager->setAttribute('model_loading', 'conservative');
?>Configuration above will make database connection and will need (require/include) on each file that need to make interaction to database. The config file above will be included on doctrine.php too.
<?php
require_once('config.php');
// save configuration that have made in config.php to an array
$config = array('data_fixtures_path' => DATA_FIXTURES_PATH,
'models_path' => MODELS_PATH,
'migrations_path' => MIGRATIONS_PATH,
'sql_path' => SQL_PATH,
'yaml_schema_path' => YAML_SCHEMA_PATH);
// use array configuration to Doctrine_Cli
$cli = new Doctrine_Cli($config);
$cli->run($_SERVER['argv']);
?>This tools can be run on command line
./doctrine
or
php doctrine.php
Command above will display list options from the tools that can be used:
Doctrine Command Line Interface doctrine.php build-all doctrine.php generate-migration doctrine.php generate-sql doctrine.php create-db doctrine.php generate-models-db doctrine.php generate-migrations-diff doctrine.php generate-migrations-db doctrine.php dump-data doctrine.php build-all-reload doctrine.php dql doctrine.php rebuild-db doctrine.php migrate doctrine.php generate-models-yaml doctrine.php create-tables doctrine.php generate-yaml-db doctrine.php generate-yaml-models doctrine.php build-all-load doctrine.php load-data doctrine.php generate-migrations-models doctrine.php drop-db doctrine.php compile
Models & Schema Files
Dalam konsep MVC model merupakan abstraksi dari database. Jadi untuk mengakses tabel yang ada di database tidak perlu lagi melakukan query, tetapi cukup membuat object dari model tersebut dan mengakses (magic) method ataupun (magic) property dari model tersebut. Pada doctrine, model tersebut bisa dibuat manual dengan mengikuti petunjuk berikut. Saya lebih suka membuat model tersebut secara otomatis, dengan membuat schema file terlebih dahulu. Setelah schema file dibuat, dengan menjalankan perintah berikut maka model pun secara otomatis dibuat oleh doctrine.
In MVC concept, model is abstraction from table on database. So, you don't need make a query to access table on database, but just make an object from that model and access (magic) method or (magic) property from that model. On doctrine, that model can be made with follow this guideline. I prefer to make that model automatically with make schema file first. Then, with run this command Doctrine will generate automatically.
./doctrine generate-models-db
Just make models don't mean you have interact with database. Because all tables on database have no created. You can insert, update, or delete from that model still saved on computer memory. To make table on database based on models, can be made automatically with this command
./doctrine create-tables
Saya akan memberikan contoh penggunaan doctrine yang menangani user dan group. Pada contoh ini user dan group mempunyai relasi many to many. Berikut ini adalah isi dari schema file.
I will give an example of doctrine usage that handle user and group. On this sample user and group have many to many relation. Here contain of schema file.
---
Group:
tableName: groups
columns:
groupId:
type: string(32)
primary: true
name: string(255)
relations:
Users:
class: User
local: groupId
foreign: userId
refClass: UserIsInGroup
User:
tableName: user
columns:
userId:
type: string(20)
primary: true
name: string(255)
password: string(255)
relations:
Group:
class: Group
local: userId
foreign: groupId
refClass: UserIsInGroup
UserIsInGroup:
tableName: user_is_in_groups
columns:
userId:
type: string(20)
groupId:
type: string(32)To make model and table on database can be done with this command
./doctrine build-all
Make sure that model have been created by doctrine, you can check the model have exists on models folder. For table on database, you can check directly in database. Doctrine also give tools to import data. But data must be prepared in data/fixtures folder in yaml format. Here data that will be imported to table on database.
---
Group:
admin:
groupId: admin
name: admin
project:
groupId: project
name: project
sudo:
groupId: sudo
name: sudo
user:
groupId: user
name: user
User:
dolly:
userId: dolly
name: Dolly Aswin Harahap
password: e10adc3949ba59abbe56e057f20f883e
root:
userId: root
name: root
password: e10adc3949ba59abbe56e057f20f883e
UserIsInGroup:
rootadmin:
userId: root
groupId: admin
dollysudo:
userId: dolly
groupId: sudo
dollyuser:
userId: dolly
groupId: userHere command to import data
./doctrine load-data
We have successfull to make models and table also import data with doctrine. Now, we can interact with models. I will give sample code to retrieve user and group with user id dolly.
<?php
// retrieve user with user id dolly
$user = Doctrine::getTable('User')->find('dolly');
echo $user->userId . ': ';
// retrieve all groups from user dolly
foreach ($user->Group as $group) {
echo $group->groupId . ',';
}
echo PHP_EOL;
?>To insert data to user table can use the way below. This code will add user id programmer to user table.
<?php
$user = new User;
$user->userId = 'programmer';
$user->name = 'Programmer';
$user->password = md5('asdf');
// add user and project to group
$user->UserIsInGroup[0]->groupId = 'user';
$user->UserIsInGroup[1]->groupId = 'project';
$user->save();
?>Berikut ini contoh kode program untuk mengubah data di tabel user. Jika dijalankan maka kode program tersebut akan mengubah password dari user id dolly dan menambahkan group id project.
Here are sample code to update data on user table. If it is ran will change password from user id dolly and add project to group
<?php
user = Doctrine::getTable('User')->find('dolly');
$user->password = md5('asdf');
// add project to group
$user->UserIsInGroup[2]['groupId'] = 'project';
$user->save();
?>Here code to delete user programmer and its relation.
<?php
$user = Doctrine::getTable('User')->find('programmer');
// delete relation
$user->UserIsInGroup->delete();
// delete user
$user->delete();
?>Migrations
Migration is my favourite feature on Doctrine. Migration is make change to database structure without destroy data on database. Doctrine will migrate based on migration classes that have made. But I prefer to make migration classes automatically. Doctrine will make it with diff schema file with the current models.
I assume we have made project release, with user, groups, and user_is_in_groups table. We want to add emailAddress field on user table for next release. To make it, just add the emailAddress field on user table structure on schema file.
User:
tableName: user
columns:
userId:
type: string(20)
primary: true
name: string(255)
password: string(255)
# tambahan field email address
emailAddres: string(125)
relations:
Group:
class: Group
local: userId
foreign: groupId
refClass: UserIsInGroupAfter added, just run this command
./doctrine generate-migrations-diff
The command above will produce migration class, and will exist in migrations folder. Here are contain of migration class that be generated by Doctrine automatically that saved with file name 1256232283_version1.php (the prefix number will different on your computer).
<?php
/**
* This class has been auto-generated by the Doctrine ORM Framework
*/
class Version1 extends Doctrine_Migration_Base
{
public function up()
{
$this->addColumn('user', 'emailaddres', 'string', '125', array(
));
}
public function down()
{
$this->removeColumn('user', 'emailaddres');
}
}
?>Migration class have been created and to affect change to model or table structure on database, just run this command
./doctrine migrate
The command above will change model and table structure on database. Doctrine also make migration_version table on database to save version of migration that have been ran.
Ok, I think that's all my explanation about doctrine usage. Thanks
Comments
Very nice, I really enjoyed
Very nice, I really enjoyed that. Is there somewhere I can read more about it?
Post new comment