The RedBeanPHP library is an ORM (Object-Relational Mapping) technology for interacting with a relational database, storing objects in it, and retrieving them.
Installing RedBeanPHP
This technology allows you to convert incompatible model types in Object-Oriented Programming (OOP), specifically between the data store and programming objects.
You can download the RedBeanPHP library from the official website. The library consists of a single file.
After downloading the file, unzip it and place it in your project. You can include the library using the function require:
require 'libs/rb.php';
Installation via Composer
Only for RedBeanPHP versions below 4.0.
Create a file composer.json with the following content:
{
"require": {
"gabordemooij/redbean": "dev-master"
}
}
In the console, run the following command:
composer install
Enable underscores
Many developers encounter a problem when using RedBeanPHP where PHP returns the following error:
However, it is possible to enable support for tables with underscores in their names, since many frameworks and CMSs use prefixes in their table names. This also applies to WordPress, which uses the prefix `wp_` for table names.
By default, RedBean does not recognize—or rather, does not allow—the use of _ underscores.
How can we bypass this validation?
To solve this problem, we need to write a small plugin (code snippet):
R::ext('xdispense', function($table_name){
return R::getRedBean()->dispense($table_name);
});
And then we create a table using xdispense:
$note = R::xdispense('lead_notes');
I found the solution on stackoverflow.com, and later I found a solution on the official RedBeanPHP website at this link.
The official website provides the following explanation:
So, if you want to use table prefixes such as `cms_` or `tbl_`, you’ll need to work around RedBeanPHP’s schema policy check as follows:
R::ext('xdispense', function( $type ){
return R::getRedBean()->dispense( $type );
});
Now you can use an underscore in your bean component’s type:
$page = R::xdispense( 'cms_page' );
However, the type name still looks a bit odd. By using a constant, you can improve the readability of this code:
define( 'PAGE', 'cms_page' );
$page = R::xdispense( PAGE );
This also works for relationships:
define( 'PAGES', 'ownCms_page' );
$pages = $site->{PAGES};
Full example:
//Define your mappings like this
define( 'POEM', 'tbl_poem' );
define( 'BOOK', 'tbl_book' );
define( 'AUTHOR', 'tbl_author' );
define( 'CATEGORY', 'tbl_category' );
define( 'POEMS', 'ownTblPoem' );
define( 'CATEGORIES', 'sharedTblCategory' );
//Create an extension to by-pass security check in R::dispense
R::ext('xdispense', function( $type ){
return R::getRedBean()->dispense( $type );
});
//Use tbl_book_category instead of tbl_book_tbl_category
R::renameAssociation([
'tbl_book_tbl_category' => 'tbl_book_category'
]);
//Use them like this:
$poem = R::xdispense( POEM );
$poem->title = 'Trees';
$author = R::xdispense( AUTHOR );
$author->name = 'Joyce Kilmer';
$book = R::xdispense( BOOK );
$book->title = 'Trees and other poems';
$category = R::xdispense( CATEGORY );
$category->name = 'nature';
$book->{AUTHOR} = $author;
$book->{POEMS}[] = $poem;
$book->{CATEGORIES}[] = $category;
$id = R::store( $book );
//For testing purposes let's output something:
$book = R::load( BOOK, $id );
$poem = reset( $book->{POEMS} );
$author = $book->{AUTHOR};
$category = reset( $book->{CATEGORIES} );
echo "Have you ever read '{$poem->title}' ({$book->title}) by {$author->name} ?
it's a beautiful poem about {$category->name}.";
This code will output:
Integrating RedBeanPHP
In the project root, create a file named index.php. In the file, include the Composer autoloader (if you used Composer) autoload.phpor include the downloaded library directly. Then connect to the MySQL database:
// Подключаем автозагрузчик composer
require_once __DIR__.'/vendor/autoload.php';
// Или: require "libs/rb.php";
// Создаём псевдоним для указанного класса
class_alias('\RedBeanPHP\R', '\R');
/**
* Подключаемся к базе данных
* Последний (4-й) параметр по умолчанию выставлен в FALSE
* Если нужно применить заморозку таблиц в БД (отменить создание на лету),
* то нужно данный параметр выставить в TRUE
* или так: R::freeze(true);
*/
R::setup( 'mysql:host=localhost;dbname=redbeanphp','root', '', false);
// Проверка подключения к БД
if(!R::testConnection()) die('No DB connection!');
/**
* Если нужно работать с таблицами, в названии которых
* присутствует знак подчёркивания (_), то необходимо воспользоваться
* таким методом
*/
R::ext('xdispense', function( $type ){
return R::getRedBean()->dispense( $type );
});
// Использовать так:
$test = R::xdispense('test_table');
// Code...
R::store($test);
To avoid having to work with aliases in the use .. as ..in each controller:
use RedBean_Facade as R;
Use the function class_alias:
class_alias('RedBean_Facade', 'R');
Creating Tables and Records
RedBeanPHP has a unique ability to create tables on the fly and insert data into them:
// Создаем таблицу users
$user = R::dispense('users');
// добавляем в таблицу необходимые записи
$user->login = $data['login'];
$user->email = $data['email'];
$user->name = $data['name'];
$user->family = $data['family'];
// Сохраняем таблицу
R::store($user);
Or here’s another example:
// Указываем, что будем работать с таблицей book
$book = R::dispense('book');
// Заполняем объект свойствами
$book->title = 'Призрак победы';
$book->price = 199;
// Можно обращаться как к массиву
$book['author'] = 'Макс Глебов';
// Сохраняем объект
R::store($book);
Reading data
If you need to retrieve data without any conditions, it’s easiest to do so using the `load()` and `loadAll()` methods. Example:
// Получаем все записи, ID которых указаны в массиве ids
$ids = [1,2,3];
$books = R::loadAll('book', $ids);
foreach ($books as $book){
echo $book->title.'
';
}
// Получаем одну запись по её ID
$id = 1;
$books = R::load('books', $id);
echo $books->title;
If, for some reason, you specifically need an array of data, there’s a method for that export():
$id = 1;
$book = R::load('book', $id);
$book = $book->export();
echo $book['title'];
Updating a Record
$id = 1;
// Загружаем объект с ID = 1
$book = R::load('book', $id);
// Обращаемся к свойству объекта и назначаем ему новое значение
$book->price = 210;
// Сохраняем объект
R::store($book);
Deleting Records Using RedBeanPHP
We’ve already read and updated data; now let’s see how to delete data using RedBeanPHP. The process is straightforward. Let’s delete a record from ID = 5:
$id = 5;
$book = R::load('book', $id);
R::trash($book);
Deleting records using ID = 6,7:
$ids = [6, 7];
$book = R::loadAll('book', $ids);
R::trashAll($book);
// Начиная с версии 5.1 данную задачу лучше выполнить методом R::trashBatch(). В таком случае нет необходимости создавать (получать) бин - объект RedBeanPHP
$ids = [6, 7];
R::trashBatch('book', $ids);
// Удаление записи с ID = 3
$id = 3;
R::hunt('book', 'id = ?', [$id]);
The method R::wipe() completely clears the specified table:
R::wipe('book');
The R::nuke() completely clears the entire database. Freeze mode must be turned off:
R::freeze(false);
R::nuke();