PHPixie 3.0 ORM или новый взгяд на ActiveRecord

image Уже закончен долгообещанная третья версия PHPixie ORM компонента. Он теперь полностью независим от фреймворка и может спокойно использоваться сам по себе. В связи с этим, пока продолжается работа над другими компонентами и пишется документация, разработчики составили небольшой туториал для того чтобы можно было уже начать работу с ОРМ. Ниже я предоставлю его перевод и добавлю несколько вещей от себя, но сначала давайте посмотрим чем полезным порадует нас эта версия: Большинство ORM используют Model классы, которые используются как для выполнения запросов так и для репрезентации самых записей в базе данных. Например так делают Kohana и Laravel. PHPixie разделила модель на Repository, Entity и Query, каждая из которых имеет строго свое предназначение. Кроме SQL баз данных (SQLite, PostgreSQL, MySQL) полностью поддерживается также Mongo. Вы сможете связать отношениями модели с SQL баз данных с моделями хранящимися в коллекциях Mongo. Чтобы поддерживать связи между разными базами (например между таблицами в разных базах в MySQL) много ORM используют отдельные запросы вместо join-ов и субзапросов. PHPixie же использует субзапросы всегда где это возможно. Поддержка встроенных сущностей в Mongo На 97% покрыта юнит тестами (планируется 100% до конца этой недели), и еще на 75% функцыоналными тестами. Эффектывное использование Query позволяет уменьшить число запросов к базе. Например вам надо связать все топики автора с какими-то тегами. В большинстве ОРМ вам придется сначала найти топики, потом теги и тогда связать их (3 запроса к БД). PHPixie позволяет сделать это за один запрос. Кстати пример этого есть в туториале снизу Надеюсь я смог вас заинтересовать, теперь посмотрим на пример с ссылки вверху в переводе:

require_once ('vendor/autoload.php');

$config = new \PHPixie\Config ();

//Инициализация компонента базы данных $database = new \PHPixie\Database ($config→dataStorage (array ( 'default' => array ( 'driver' => 'pdo', 'connection' => 'sqlite: memory:' ) )));

//И самой ОРМ $orm = new \PHPixie\ORM ($database, $config→dataStorage (array ( 'relationships' => array ( array ( //У феи может быть много цветов 'type' => 'oneToMany', 'owner' => 'fairy', 'items' => 'flower' ) ) )));

//Создание табличек $connection = $database→get ('default');

$connection→execute (' CREATE TABLE fairies ( id INTEGER PRIMARY KEY, name VARCHAR (255) ) ');

$connection→execute (' CREATE TABLE flowers ( id INTEGER PRIMARY KEY, name VARCHAR (255), fairy_id INTEGER ) ');

//Моделей больше не существует //Их заменяют Repositories, Entities и Query

/* Мы все ненавидим когда сущности также являются запросами: $fairy→name = 'Trixie'; $fairy→save (); $fairy→where ('name', 'Stella')→find (); */

//Репозитории создаются автоматически для существующих табличек $fairyRepository = $orm→get ('fairy'); $flowerRepository = $orm→get ('flower');

//Это все была инициализация //А теперь приступим

//Создадим несколько фей

$trixie = $fairyRepository→create (); $trixie→name = 'Trixie'; $trixie→save ();

//Версия покороче $fairyRepository →create (array ('name' => 'Stella')) →save ();

//А еще нам понадобятся цветки

foreach (array ('Red', 'Yellow', 'Green', 'Purple') as $name) { $flowerRepository →create (array ('name' => $name)) →save (); }

//А теперь создадим Query //аналог WHERE `id` > 1 AND (`name` = 'Green' OR `name` = 'Red') $green = $flowerRepository→query () →where ('id', '>', 1) →startAndWhereGroup () →where ('name', 'Green') →or ('name', 'Red') →endGroup () →findOne ();

//или лаконичнее $green = $flowerRepository→query () →where ('id', '>', 1) →and (function ($q){ $q →where ('name', 'Green') →or ('name', 'Red') }) →findOne ();

//Связи //Каждая связь добавляет свойства в Сущности и Запросы //В нашем случае свойство 'flowers' предоставляет методы add (), remove () и removeAll () //Это намного удобнее чем методы addFlower (), removeFlower () и removeAllFlowers () на самом объекте $trixie→flowers→add ($green);

//При связывании объектов, значение кешируется сразу в обе стороны //чтобы избежать дополнительных запросов к базе //В даном случае это кажется на таким уж важным, так как добиться такого эффекта //для oneToMany достаточно просто. Но для manyToMany оно тоже будет работать assert ($green→fairy () == $trixie);

//Теперь попробуем связать все цветы кроме Green c феей Stella //И уложиться в один запрос

//Зададим запрос который нашел бы Стеллу $stellaQuery = $fairyRepository→query () →where ('name', 'Stella');

//И запрос который найдет цветы $allExceptGreen = $flowerRepository→query () →whereNot ('name', 'Green');

//И теперь магия $stellaQuery→flowers→add ($allExceptGreen);

//Также Query позволяет изменять сущности без выборки //Например переименуем цветок Purple в Blue $flowerRepository→query () →where ('name', 'Purple') →update (array ( 'name' => 'Blue' ));

//Можно найти фею у которой есть определенный цветок: $trixie = $fairyRepository→query () →relatedTo ('flowers', $green) →findOne ();

//А теперь найдем всех фей у которых есть хотя бы один цветок //И сразу подгрузим все их цветки $fairies = $fairyRepository→query () →relatedTo ('flowers') →find (array ('flowers')); //так задается прелоудинг связей

//И выведем их как простые объекты //Удобно для json_encode () print_r ($fairies→asArray (true));

//Больше примеров потом =) Попробовать этот пример у себя достаточно просто:

git clone https://github.com/phpixie/orm cd orm/examples #если у вас еще нет Композера curl -sS https://getcomposer.org/installer | php php composer.phar install php quickstart.php Эта ORM разрабатывалась больше года и нам очень интересны все вашы вопросы и замечания, очень ждем комментариев. А если вам интересно узнать о будущих компонентах и самом фреймворке то не забудьте подписаться на твиттер @phpixie

© Habrahabr.ru