A Doctrine tulajdonképpen az adatbázis sémákat képezi objektumokra. Pl a következő kód egy falhasználót reprezentál:
class User extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('username', 'string', 255);
$this->hasColumn('password', 'string', 255);
}
public function setUp()
{
$this->actAs('Timestampable');
}
}
Minden Doctrine_Record-nak van egy setTableDefinition() és setUp() metódusa. A setTableDefinition() a tábla sémáját definiálja, a setUp()
metódusban pedig a viselkedéseket és az adatbáziskapcsolatokat írjuk le. A fenti példában a Timestampable viselkedést használjuk, ami
egy automatikus funkcionalitást ad a kódhoz.
A Doctrine több lehetőséget biztosít ezen osztályok generálására.
Generálás adatbázisból
Van lehetőségünk arra, hogy már létező adatbázist használjunk, és abból generáljunk Dictrine_Record osztályokat. Tegyük fel, hogy a
doctrine_test adatbázisban egyetlen táblánk szerepel:
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
Ezt szeretnénk Doctrine_Record-á konvertálni. Hozzunk létre egy doctrine_test/models könyvtárat. A konfigurációs kód végén futtassuk a következőt:
Doctrine_Core::generateModelsFromDb('models', array('doctrine'), array('generateTableClasses' => true));
A metódusban szereplő paraméterek
- A könyvtár, ahova generálni akarjuk a kódot (kötelező)
- az adatbázis kapcsolat
- módosítók tömbje
A doctrine_test/models/generated alkönyvtárban létrejön egy fájl:
// 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));
}
}
A doctrine_test/models/ könyvtárban is létrejön két fájl:
// models/User.php
/**
* This class has been auto-generated by the Doctrine ORM Framework
*/
class User extends BaseUser
{
}
// models/UserTable.php
/**
* This class has been auto-generated by the Doctrine ORM Framework
*/
class UserTable extends Doctrine_Table
{
}
Ezekkel a fájlokkal tudunk funkcionalitást hozzáadni a legeneráltakhoz. Pl. azt szeretnénk, hogy a password mező automatikusan
MD5-tel kódolva tárolódjon az adatbázisba, használhatjuk a következő kódot:
// models/User.php
// ...
class User extends BaseUser
{
public function setPassword($password)
{
return $this->_set('password', md5($password));
}
}
Hogy ez működjön, a manager-en engedélyezni kell a auto_accessor_override attribútumot:
// bootstrap.php
// ...
$manager->setAttribute(Doctrine_Core::ATTR_AUTO_ACCESSOR_OVERRIDE, true);
Ezen kívül inlude-olni kell a models mappában sorakozó fájlokat
// bootstrap.php
// ...
Doctrine_Core::loadModels('models');
Most már le tudjuk tesztelni az User osztályunkat:
// test.php
// ...
$user = new User();
$user->username = 'jwage';
$user->password = 'changeme';
echo $user->password; // outputs md5 hash and not changeme
Az UserTable-höz is hozzá adhatunk egy-két funkciót:
// 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();
}
}
Hogy ez működjön, a manager-en engedélyezni kell a autoload_table_classes attribútumot:
// bootstrap.php
// ...
$manager->setAttribute(Doctrine_Core::ATTR_AUTOLOAD_TABLE_CLASSES, true);
Ez akkor fog működésbe lépni, ha az UserTable osztályt használjuk:
// test.php
// ...
$usersCreatedToday = Doctrine_Core::getTable('User')->getCreatedToday();
Séma fájlok
A sémát YAML fájlok segítségével is megadhatjuk. Ezek az XML-hez hasonló leírófájlok. Ezekből generálhatók a felt leírt php fájlok.
A következő sorral generálható php fájl a schema.yml-ből:
// test.php
// ...
Doctrine_Core::generateYamlFromModels('schema.yml', 'models');
Lássuk magát a schema.yml-t:
---
User:
tableName: user
columns:
id:
type: integer(8)
primary: true
autoincrement: true
is_active:
type: integer(1)
default: '1'
is_super_admin:
type: integer(1)
default: '0'
created_at:
type: timestamp(25)
notnull: true
updated_at:
type: timestamp(25)
notnull: true
first_name: string(255)
last_name: string(255)
username: string(255)
password: string(255)
type: string(255)
A fájlban létre hozunk összesen egy User nevű entitást, ami az user nevű táblára képződik le. A táblának 10 mezője van. Ha a mezőnek
csak a típusát adjuk meg, írhatjuk a változó neve után közvetlenül, kettősponttal elválasztva. Minden tulajdonságnak van egy alapértelmezett
értéke, ezeket meg tudjuk változtatni, ha a név utáni sorokban egy behúzással felsoroljuk a tulajdonságokat és az értékeit.
A YAML fájl-ból most már csak le kell generálni a php fájlokat. Ehhez hozzunk létre egy generátort:
// generate.php
require_once('bootstrap.php');
Doctrine_Core::dropDatabases();
Doctrine_Core::createDatabases();
Doctrine_Core::generateModelsFromYaml('schema.yml', 'models');
Doctrine_Core::createTablesFromModels('models');
Változtassunk a YAML fájlon úgy, hogy most a következőképpen nézzen ki:
---
User:
actAs: [Timestampable]
columns:
is_active:
type: integer(1)
default: '1'
is_super_admin:
type: integer(1)
default: '0'
first_name: string(255)
last_name: string(255)
username: string(255)
password: string(255)
type: string(255)
Néhány változás:
- Nem adjuk meg a tábla nevét, az automatikusan user lesz
- Beállításra került a Timestampable viselkedés.
- Az id oszlop eltávolításra került, ha nincs definiálva primary key, akkor ez automatikusan létrejön.
- Az updated_at és created_at oszlopok eltávolításra kerültek, a Timestampable viselkedéssel ezek automatikusan létrejönnek.
Látható, hogy a YAML fájl mennyivel barátságosabb, és hogy a viselkedések mennyire meg tudják könnyateni a dolgunkat.