Doctrine Object Relational Mapper

Modell használata

A Doctrine alacsony szintjén a sémát php osztályok halmaza reprezentálja, amit adatbázistáblákra képezünk le. Ez a fejezet arról szól, hogyan képezzük le az osztályokat adatbázistáblákra.

Tesztséma létrehozása

A következőkben ezzel a sémával fogunk dolgozni:

// models/User.php class User extends Doctrine_Record { public function setTableDefinition() { $this->hasColumn('username', 'string', 255, array( 'type' => 'string', 'length' => '255' ) ); $this->hasColumn('password', 'string', 255, array( 'type' => 'string', 'length' => '255' ) ); } public function setUp() { $this->hasMany('Group as Groups', array( 'refClass' => 'UserGroup', 'local' => 'user_id', 'foreign' => 'group_id' ) ); $this->hasOne('Email', array( 'local' => 'id', 'foreign' => 'user_id' ) ); $this->hasMany('Phonenumber as Phonenumbers', array( 'local' => 'id', 'foreign' => 'user_id' ) ); } } // models/Email.php class Email extends Doctrine_Record { public function setTableDefinition() { $this->hasColumn('user_id', 'integer', null, array( 'type' => 'integer' ) ); $this->hasColumn('address', 'string', 255, array( 'type' => 'string', 'length' => '255' ) ); } public function setUp() { $this->hasOne('User', array( 'local' => 'user_id', 'foreign' => 'id' ) ); } } // models/Phonenumber.php class Phonenumber extends Doctrine_Record { public function setTableDefinition() { $this->hasColumn('user_id', 'integer', null, array( 'type' => 'integer' ) ); $this->hasColumn('phonenumber', 'string', 255, array( 'type' => 'string', 'length' => '255' ) ); $this->hasColumn('primary_num', 'boolean'); } public function setUp() { $this->hasOne('User', array( 'local' => 'user_id', 'foreign' => 'id' ) ); } } // models/Group.php class Group extends Doctrine_Record { public function setTableDefinition() { $this->setTableName('groups'); $this->hasColumn('name', 'string', 255, array( 'type' => 'string', 'length' => '255' ) ); } public function setUp() { $this->hasMany('User as Users', array( 'refClass' => 'UserGroup', 'local' => 'group_id', 'foreign' => 'user_id' ) ); } } // models/UserGroup.php class UserGroup extends Doctrine_Record { public function setTableDefinition() { $this->hasColumn('user_id', 'integer', null, array( 'type' => 'integer', 'primary' => true ) ); $this->hasColumn('group_id', 'integer', null, array( 'type' => 'integer', 'primary' => true ) ); } }

Ugyanez YAML fájlban:

--- # schema.yml User: columns: username: string(255) password: string(255) relations: Groups: class: Group local: user_id foreign: group_id refClass: UserGroup foreignAlias: Users Email: columns: user_id: integer address: string(255) relations: User: foreignType: one Phonenumber: columns: user_id: integer phonenumber: string(255) primary_num: boolean relations: User: foreignAlias: Phonenumbers Group: tableName: groups columns: name: string(255) UserGroup: columns: user_id: type: integer primary: true group_id: type: integer primary: true

Relációk

Rekord létrehozása

Háromféleképpen is elérhetőek a példány property-jei, habár az utolsó verzió a javasolt, a tömbös portolhatóság miatt.

// test.php // ... $user = new User(); $user['username'] = 'jwage'; $user['password'] = 'changeme'; $email = $user->Email; $email = $user->get('Email'); $email = $user['Email'];

Ha egy one-to-one kapcsolaton keresztül próbálunk elérni egy nem létező objektumot, a Doctrine automatikusan létrehozza.

// test.php // ... $user->Email->address = 'jonwage@gmail.com'; $user->save();

Ha egy one-to-many kapcsolaton keresztül próbálunk elérni egy nem létező objektumot, a Doctrine létrehoz egy Doctrine_Collection példányt a kapcsolódó komponenshez. Pl vannak felhasználóink, telefonszámaink, és a köztük lévő one-to-many kapcsolat. Így adhatunk a felhasználóhoz telefonszámokat:

// test.php // ... $user->Phonenumbers[]->phonenumber = '123 123'; $user->Phonenumbers[]->phonenumber = '456 123'; $user->Phonenumbers[]->phonenumber = '123 777';

Most már könnyen elmenthetjük a felhasználót, és a hozzá kapcsolódó telefonszámokat:

// test.php // ... $user->save();

Egy másik módszer, hogy összekapcsoljuk két komponenst a Doctrine_Record::link(). Pl van két objektumunk, amit össze szeretnénk kötni egymással. Ebben az esetben ha a két rekord között fennáll egy kapcsolat, csak a rekord azonosítójára van szükség

Hozzunk létre néhány új Phonenumber objektumot, és tároljuk az új telefonszámok azonosítóit:

// test.php // ... $phoneIds = array(); $phone1 = new Phonenumber(); $phone1['phonenumber'] = '555 202 7890'; $phone1->save(); $phoneIds[] = $phone1['id']; $phone2 = new Phonenumber(); $phone2['phonenumber'] = '555 100 7890'; $phone2->save(); $phoneIds[] = $phone2['id'];

Kössük a telefonszámokat egy felhasználóhoz

// test.php $user = new User(); $user['username'] = 'jwage'; $user['password'] = 'changeme'; $user->save(); $user->link('Phonenumbers', $phoneIds);

Ha a User és a Phonenumber rekord osztályok között fennáll a kapcsolat, akkor ezt megtehetjük.

Hozzunk létre egy felhasználót:

// test.php // ... $user = new User(); $user['username'] = 'jwage'; $user['password'] = 'changeme'; $user->save();

Hozzunk létre egy telefonszámot:

// test.php // ... $phone1 = new Phonenumber(); $phone1['phonenumber'] = '555 202 7890'; $phone1->save();

Kössük össze a kettőt:

// test.php // ... $phone1->link('User', array($user['id']));

Hozzunk létre egy új telefonszámot:

// test.php // ... $phone2 = new Phonenumber(); $phone2['phonenumber'] = '555 100 7890'; $phone2->save();

Kössük azt a telefonszámot is a felhasználónkhoz:

// test.php // ... $phone2->link('User', array($user['id']));