Хотелось бы узнать будет ли полезна кому-то система по работе с persistent объектами на PHP. На протяжении нескольких лет она уже работает на большом количестве коммерческих проектов с закрытым исходным кодом. И т.к. за эти годы, ничего похожего не появилось — хотелось бы знать — заинтересует ли кого-то.
Система разрабатывалась по принципу — как было бы удобно, чтобы именно ООП, без миксования работы с одной сущностью и коллекциями сущностей, ну и без дополнительных структур для хранения данных. И… без оглядки на какие-либо паттерны.
В синтаксисе — основной метод получения сущностей — через статические методы. Т.е. довольно часто можно встретить такое, что статический метод класса вернёт объект этого самого класса.
Всё что нужно сделать для того, чтобы объект начал сохраняться, получаться из базы данных (т.е. стал постоянным) нужно всего-лишь написать следующее:
class User extends DataObject{
}
Т.е. заэкстендиться от класса DataObject
Чтобы получить пользователя:
class User extends DataObject{
/**
* Will return user by id
* @param int $userId
* @return User
*/
public static function getById($userId){
return parent::_getByCondition(array('user_id'=>$userId),__CLASS__,'users');
}
}
Вот так просто. Можно аналогичным образом сделать ещё getByName и что угодно ещё. У объекта узер появятся get, set, save методы. Кроме парентового статического метода _getByCondition есть _getByQuery, _create.
Сам класс юзера может выглядеть так:
class User extends DataObject{
const TABLE='users';
/**
* Will return country of the user
*
* @return Country
*/
public function getCountry(){
return Country::getById($this->get('country_id'));
}
/**
* Will return user by id
*
* @param int $userId
* @return User
*/
public static function getById($userId){
return parent::_getByCondition(array('user_id'=>$userId),__CLASS__,self::TABLE);
}
/**
* Will return user by email
*
* @param string $email
* @return User
*/
public static function getByEmail($email){
return parent::_getByCondition(array('email'=>$email),__CLASS__,self::TABLE);
}
/**
* Will create user
*
* @param string $email
* @param string $password
* @param string $firstName
* @param string $lastName
* @return User
*/
public static function create($email,$password,$firstName,$lastName,Country $country){
return parent::_create(array('email'=>$email,
'password'=>$password,
'first_name'=>$firstName,
'last_name'=>$lastName,
'country_id'=>$country->getId()),__CLASS__,self::TABLE,'id');
}
}
Далее можно, например, создать пользователя и немного поманипулировать данными.
echo User::create('vasja@pupkin.com','123','Vasja','Pupkin')->getCountry()->getCurrency()->getCode();
Пользователь полученный разными методами — getById и getByEmail — будут ссылками на один и тот же объект.
По сути — один рядок в таблице соответствует одному объекту.
Для работы с несколькими объектами есть DataObjectGroup и аналогичным образом для того, чтобы этот объект был коллекцией — нужно заэкстендить специальный класс DataObjectGroup.
class UsersGroup extends DataObjectGroup{
/**
* Will return premium users (UsersGroup of Users)
*
* @return UsersGroup
*/
public static function getPremiumMembers(){
return parent::_getByCondition(array('is_permium'=>1),__CLASS__,'User',User::TABLE,'id');
}
}
Далее можно сделать, например, такое:
foreach(UsersGroup::getPremiumMembers()->orderBy('registration_date')->limit(10) as $user){
/**<hh user=var> User $user*/
echo $user->getCountry()->getCurrency()->getCode()."<br />";
}
Это лишь основные возможности и принципы.
Очень приятно работать с такой структурой — всё чётко и очевидно. Кроме того, легко привязывается куда угодно, включая
говносайты сайты с нечёткой структурой, куда постепенно нужно прибавить структурности.
Почему не сразу в статью — нужна ещё привязка к какой-либо популярной прослойке работы с БД (например, pdo), немного заполировать, выбрать название и чтобы это сделать — прежде всего нужно знать — найдутся ли те, кому это нужно, либо всем достаточно существующих решений, например — Doctrine 2.
Всё работает с PHP5.2+