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']));