Doctrine Object Relational Mapper

Modell - Bevezetés

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 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)