Главная » Полезные статьи » Язык PHP » В PHP 5.3 появился ActiveRecord аналогичный Ruby on Rails
Распечатать статью

В PHP 5.3 появился ActiveRecord аналогичный Ruby on Rails

Поиски решения активной записи в php были изнурительны до того момента, как один из источников в google не предложил вариант ActiveRecord аналогичный Ruby on Rails. Читатель заметит, что вышеупомянутые результаты слишком устаревшие и большая часть из них мало общего с действенностью.

В конце концов, PHP получит более надежный способ активной записи аналогичный способу применяемому в RoR. И, к счастью, это время настало! Спасибо PHP 5. 3 и его новым полезным функциям: схлопыванию, позднему статистическому связыванию и пространству имен.

Я со своим другом Каеном, внесли улучшения в раннюю версию на базе ORM, которую он написал до появления PHP 5. 3. Мы создали ActiveRecord вдохновленные Ruby on Rails и попытались сохранить его возможности, насколько это было возможно. Нашей основной целью в этом проекте – дать возможность PHP-разработчикам создавать крупные проекты с большей гибкостью.

Мы также надеемся что использование данного продукта подтолкнет PHP сообщество к дальнейшему осознанию всех замечательных преимуществ Ruby on Rails. Ладно , хватит крутиться вокруг да около, давайте перейдем к самому интересному!

Обзор ActiveRecord

Позвольте мне согласиться с тем фактом, что мы пытались сохранить сходство между нашим детящем и ActiveRecord на базе Ruby on rails, чтобы избежать головной боли и повысить работоспособность программиста. Сохраняя это сходство, мы постарались воссоздать многие функции. Вот список этих функций:

  • Методы поиска
  • Методы динамического поиска
  • Методы записи
  • Отношения
  • Верификация
  • Обратные вызовы
  • Сериализация
  • Поддержка различных драйверов
  • Другие параметры

Также здесь есть и другие возможности, как пространства имен, дополнительные драйверы, транзакции (то чего мы хотели бы пораньше) и многое другое мы добавим в будущем, но для начала я думаю совсем неплохо. Мы надеемся, запустить сайт с документацией и разместить исходники на сервисе исходных кодов в течении 2-3х недель. Не забывайте следить за обновлениями, которые вскоре появятся.

Конфигурация

Установка проста и линейна. Здесь есть всего 2 типа конфигурации, которые вы можете выбрать:

  • Установка типовой auto_load директории
  • Настройка соединений с вашей базой данных

Примеры:

ActiveRecord\Config::initialize(function($cfg) { $cfg->set_model_directory('/path/to/your/model_directory'); $cfg->set_connections(array('development' => 'mysql://username:password@localhost/database_name')); }); #Альтернативно(w/o ограничение 5.3): $cfg = ActiveRecord\Config::instance(); $cfg->set_model_directory('/path/to/your/model_directory'); $cfg->set_connections(array('development' => 'mysql://username:password@localhost/database_name'));

Как только вы настроите два этих параметра ваша работа окончена. ActiveRecord заботится о вас и берет остальную часть работы на себя. Она не требует проводить какую либо дополнительную работу со схемами ваших yaml/xml файлов. Также запросы к базу данных для получения информации и кэш-файлов будет проходить без лишних вызовов для одной схемы.

Методы поиска

ActiveRecord поддерживает несколько методов, с помощью которых, вы можете найти записи либо по первичному ключу, либо сконструировав свой собственный с набором опций, к примеру: сортировка, лимит, выбор, группировка.

#поиск по первичному ключу Author::find(3); #поиск нескольких записей по первичному ключу Author::find(1, 2, 3); #поиск первой записи по лимиту Author::first(); #поиск последней записи по сортировке и лимиту Author::last(); Author::all(); #это возможно будет для вас адом, но вы должны выполнить свой sql-запрос для поиска Author::find_by_sql(); ## еще вы можете добавить много дополнительных опций к методам поиска #sql => ORDER BY name Author::find(3, array('order' => 'name')); #sql => WHERE author_id IN (1, 2, 3) # поиск с условиями как массив Author::find('all', array('conditions' => array('author_id IN(?)', array(1, 2, 3)))); #sql => WHERE author_id = 3 #поиск с условиями как строка Author::find('first', array('conditions' => 'author_id=3')); #sql => GROUP BY name Author::find(3, array('group' => 'name')); #sql => LIMIT 0, 3 Author::find('all', array('limit' => 3)); #sql => select * from `author` INNER JOIN etc. . . Author::find('all', array('joins' => 'INNER JOIN book on (book. author_id = author. id)')); #sql => SELECT name FROM table Author::first(array('select' => 'name')); #этод метод не возвращает запись #возвращает да/нет Author::exists(1); #возвращает число Author::count(array('conditions' => array('name = ?', 'John'))); #доступ очень простой $book = Book::first(); echo $book->title; echo $book->author_id; # возвращает массив $books = Book::all(); echo $books[0]->title;

 

Методы динамического поиска

ActiveRecord на основе RoR расширяет функции использования поиска, позволяя динамически создавать методы основанные на атрибутивных именах. Это значит, вы с легкостью можете сделать запрос»find_by_attribute_name» без явного классового определения. Мы сделали это возможным с помощью использования волшебного метода в PHP 5.3: __callStatic().

Author::find_by_name('George Bush'); #вы можете это сделать используя и/или Author::find_by_name_or_author_id('George Bush', 2); Person::find_by_first_name_and_last_name('Obama', 'Mama'); #также имеется find_all_by(найти всё по какому-либо параметру) Author::find_all_by_name('Tito'); Author::find_all_by_name(array('Tito', 'Bill Clinton'));

 

Методы записи

Какой смысл иметь объект, который инкапсулирует запись из БД, если вы не можете ничего сделать с этим?

#выполняет SQL insert, такой же какой вы делаете при добавлении записи $book = new Artist(array('name' => 'Tito')); $book->save(); ## обновление # обновление возможно, только после нахождения обновляемой строки $book = Book::find(1); $book->title = 'new title!'; $book->save(); #это автоматически выполняет сохранение $book = Book::find(1); $book->update_attributes(array('title' => 'new title!', 'price' => 5. 00)); #еще автоматическое сохранение $book = Book::find(1); $book->update_attribute('title', 'some new title'); $book = new Book; $book->title = 'new title!'; $book->author_id = 5; $book->save(); $book->created_at # мы также поддерживаем временные отметки created_at/updated_at где это нужно echo $book->id; #id также получает авто инкрементированное значение #удаление $author = Author::find(4); $author->delete(); #вы получаете запись в режими только чтение без возможности изменить её $book = Book::first(array('readonly' => true)); $book->title = 'new'; # или вы можете установить этот режим с помощью метода $book->readonly(true); #это запустит процессы ActiveRecord\ReadonlyException $book->save();

 

Отношения

Объединения — сложная часть ActiveRecord. Они используют те же самые опции, что в RoR.

#отношения декларируются в статическом свойстве class Book extends ActiveRecord\Model { static $belongs_to = array( array('publisher'), array('author', 'readonly' => true, 'select' => 'name', 'conditions' => "name != 'jax'"), array('another', 'class_name' => 'SomeModel') ); #has_many допускает select/conditions/limit/readonly/group/primary_key #has_many также применима через опцию которую вы можете использовать с источником(source) #для уточнения класса static $has_many = array( array('revisions'), array('editors', 'through' => 'revisions') ); static $has_one = array( array('something') ); } #индекс декларируемый для каждой ассоциации является "attribute_name" #которую вы можете использовать для работы с моделью как, например: $book = Book::first(); echo $book->publisher->name; echo $book->author->name; # у нас есть только имя как атрибут выборки #ниже будет запускаться опция readonlyException — смотрите методы записи #методы выбора $book->author->save(); #has_many echo $book->revisions[0]->id; #has_many echo $book->editors[0]->name;

 

Верификация

Название говорит само за себя. До того как сохранить/обновить/извлечь к каждому определению, которое вы создали, будет применена верификация и только после её удачного прохождения модель будет возвращена. В противном случае, вы увидите сообщение об ошибке и сможете вернуться обратно для ее исправления.

class Book extends ActiveRecord\Model { static $validates_format_of = array( array('title', 'with' => '/^[a-zW]*$/', 'allow_blank' => true) ); static $validates_exclusion_of = array( array('title', 'in' => array('blah', 'alpha', 'bravo')) ); static $validates_inclusion_of = array( array('title', 'within' => array('tragedy of dubya', 'sharks wit laserz')) ); static $validates_length_of = array( array('title', 'within' => array(1, 5)), array('attribute2', 'in' => array(1, 2)), array('attribute3', 'is' => 4, 'allow_null' => true) ); # same as above since it is just an alias static $validates_size_of = array(); static $validates_numericality_of = array( array('title') ); static $validates_presence_of = array( array('title') ); }; $book = new Book; $book->title = 'this is not part of the inclusion'; if (!$book->save()) print_r($book->errors->on('title'));

 

Обратные вызовы

Обратные вызовы дают вам возможность управлять вашей моделью до/после какого-то события на протяжении ее существования. Вы можете выбрать методы, которые будут вызваны как callback до или после других методов примененных в модели. К сожалению, даже PHP 5.3 имеет ограничения — вы не можете иcпользовать callback в виде статических методов, они должны быть динамическими.

#Ниже приведены команды, которые вы можете использовать #Если ваш обратный вызов является недействительным для before_*, он отменит #действие и остальные вызовы class Book extends ActiveRecordModel{ static $after_construct; static $before_save = array('do_something_before_save'); static $after_save; static $before_create; static $after_create; static $before_update; static $after_update; static $before_validation; static $after_validation; static $before_validation_on_create; static $after_validation_on_create; static $before_validation_on_update; static $after_validation_on_update; static $before_destroy; static $after_destroy; #это будет вызвано перед обновлением public function do_something_before_save() {} }

 

Сериализация

 

class Book extends ActiveRecord\Model{ public function upper_title(){ return strtoupper($this->title); } } #produces: {title: 'sharks wit lazers', author_id: 2} $book = Book::find(1); $book->to_json(); #produces: {title: 'sharks wit lazers'} $book->to_json(array('except' => 'author_id')); #produces: {upper_title: 'SHARKS WIT LAZERS'} #создает массив методов, которые затем будут вызваны $book->to_json(array('methods' => 'upper_title', 'only' => 'upper_title')); #produces {title: 'sharks wit lazers', author_id: 2} $book->to_json(array('include' => array('author'))); #также поддерживает xml, который имеет теже опиции, но нужны больше для тестирования =) $book->to_xml();

 

Поддержка различных драйверов

В настоящее время существует поддержка только для MySQL (через mysqli) и sqlite3. Однако мы надеемся ввести большее число драйверов в проект, что должно помочь в работе с такими БД как PostgresSQL и Oracle. Соедиение/адаптер — сделан так, что не возникнет никаких затруднений при создании большего числа драйверов, когда будет нужно.

Другие параметры

При декларировании модели вы также можете указать primary_key и table_name.
Защищенные/доступные определения уже доступны, так что вы можете справится со многими распространенными проблемами. Атрибуты могут быть псевдонимами, чтобы вам было легче получить доступ к ним через разные имена.

class Book extends ActiveRecord\Model{ static $primary_key = 'book_id'; static $table_name = 'book_table'; static $attr_accessible = array('author_id'); static $attr_protected = array('book_id'); static $alias_attribute = array( 'new_alias' => 'actual_attribute', 'new_alias_two' => 'other_actual_attribute' ); }

 

Будущее

Как я уже отмечал ранее, в самое ближайшее время данный код будет доступен на сервисах исходного кода. Мы также работаем над созданием сайта с учебными пособиями и документациями к коду. Я буду сообщать о новых успехах.
Спасибо за прочтение!

UPD: ActiveRecord доступен по адресу http://github.com/kla/php-activerecord/tree/master

Данная статья является переводом PHP ActiveRecord with PHP 5.3.
Подготовленно командой Internet-Technologies.Ru

Источник: internet-technologies.ru

Вы можете оставить комментарий, или обратную ссылку на Ваш сайт.

Оставить комментарий

Похожие статьи