RedBean PHP ORM – за и против

Владимир | | MySQL, PHP, Web разработка.

Приветствую всех!

Сегодня я хочу рассказать о небольшой ORM библиотеке под названием RedBean с которой я на днях экспериментировал.

Прежде всего, пару слов о ORM (англ. Object-relational mapping, русск. Объектно-реляционная проекция) вообще.

Основное назначение таких библиотек – преобразование объектов, которые используются в программах, в записи реляционных баз данных и обратно.

Дело в том, что все данные в БД хранятся в таблицах (аналог двумерных массивов), а объекты могут быть организованы в сложные иерархии (например, объект типа «Post» может содержать массив объектов типа «Comment»). И для того, чтобы сохранить такую структуру в БД нужно использовать несколько таблиц с дополнительными полями, которые устанавливают связи между записями.

Все это увеличивает сложность SQL запросов и время разработки.

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

Вернемся к RedBean.

Проиллюстрировать работу любой библиотеки проще всего на примере. Поэтому я написал небольшой скрипт.

<?php 
include 'oodb.php';

//подключаемся к БД
RedBean_Setup::kickstartDev('Post,Comment','mysql:host=localhost;dbname=my_database', 'user_name', 'password');

$post = new Post();
$post->title = 'Новая запись';
$post->content = 'Просто какой-то текст';
$id = $post->save();

$comment = new Comment;
$comment->author = 'admin';
$comment->text = 'Очень простой комментарий';
$comment->belongsTo($post);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="language" content="en" />
<title>Test RedBean</title>
</head>

<body>

<ul>
<?php
$posts = Post::listAll();
foreach ($posts as $post) {
	$curPost = new Post($post['id']);
	echo '<li><strong>'.$curPost->getTitle().'</strong><br />';
	echo $curPost->getContent();
	$comments = $curPost->getRelatedComment();
	echo '<ol>';
	foreach ($comments as $comment) {
		echo '<li>'.$comment->text.' ('.$comment->author.')</li>';
	}
	echo '</ol></li>';
}
?>
</ul>

</body> </html>

Посмотрим, что он делает.

1) Подключаем библиотеку (строка 2). Тут объяснять нечего, RedBean состоит всего из одного файла.

2) Подключаемся к базе данных и создаем объекты, которые будем в ней хранить (строка 5).
Обе операции выполняются с помощью метода kickstartDev. В первом параметре мы указываем перечень нужных объектов (они будут создаваться динамически). В остальных параметрах – данные, необходимые для подключения к базе (dns, имя пользователя и пароль).

Предварительно от нас требуется только создать пустую БД. Созданием таблиц, сохранением и чтением данных будет заниматься RedBean.

Примечание. Метод kickstartDev переводит библиотеку в т.н. fluid режим. При этом если вы измените, количество или названия свойств объектов, то RedBean автоматически изменит структуру таблиц в БД. Этот режим имеет смысл использовать во время разработки. После переноса приложения на «боевой» сервер kickstartDev лучше заменить на kickstartFrozen. Библиотека перейдет во frozen режим, при этом таблицы автоматически изменяться не будут, но и потребление ресурсов сократится.

3) Создаем данные и сохраняем их в БД (строки 7-15).

В данном случае создано два объекта типов Post и Comment, каждый из которых содержит несколько свойств.
Обратите внимание, что свойства создаются автоматически. От нас требуется указать только название свойства и его значение.
Мы просто присваиваем значения нужным свойствам и вызываем метод save(), который записывает объект в БД (строка 10).

Объект Comment принадлежит Post. Эту связь мы устанавливаем с помощью метода belongsTo. При этом использовать save не нужно. Сохранение в БД произойдет автоматически.

4) Читаем данные из базы (строки 29-40).
Тут тоже все достаточно прозрачно. С помощью статического метода listAll мы получаем массив со всеми объектами типа Post, находящимися в БД.

Чтобы получить доступ к комментариям мы создаем объект типа Post (строка 31) и при этом в качестве параметра указываем id.

После этого мы можем использовать метод getRelatedComment для получения массива с комментариями.
Примечание. Название метода getRelatedComment формируется следующим образом. К приставке getRelated добавляется имя объекта, который мы хотим получить.

Затем в цикле мы выводим комментарии.

В результате выполнения скрипта вы увидите такую страницу.

pic1

Теперь посмотрим, что у нас делается с базой данных.

Прежде всего, взгляните на перечень таблиц.

pic2

Как видите, RedBean создал 6 таблиц. Три из них (post, comment_post и comment) используются для хранения данных приложения, остальные – используются самой RedBean.

Теперь посмотрим, что сохранено в самих таблицах.

post

pic3

comment_post

pic4

comment

pic5

Думаю, вы уже догадались, в чем дело.

Между объектами Post и Comment отношение типа ОДИН-К-МНОГИМ и для его реализации не нужна промежуточная таблица. Т.е. если бы база создавалась вручную, мы бы обошлись всего двумя таблицами. Соответственно, упрощаются и SQL запросы.

Использовать или не использовать?

Это вопрос философский 🙂 . RedBean не единственная ORM библиотека. Например, существуют более мощные Propel и Doctrine.

Ответ будет зависеть от требований к конкретному приложению. В общем случае при использовании ORM увеличивается скорость разработки и упрощается поддержка, но при этом растет потребление ресурсов.

К тому же стоит учесть время, необходимое на изучение библиотеки. В этом RedBean значительно превосходит библиотеки типа Doctrine. Вряд ли у вас уйдет больше пары дней на эксперименты с RedBean.

В общем, думаю, что в ряде случаев использование RedBean будет вполне оправданно.

В заключение хочу сказать, что это статью нельзя рассматривать как руководство по использованию библиотеки. Поэтому я очень рекомендую вам почитать документацию на сайте.