The RedBeanPHP Library for Working with Databases

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:

Fatal error: Uncaught RedBeanPHP\RedException: Invalid type

Warning! By default, RedBean does not allow underscores in database table names; that is, in this library, underscores are used to denote relationships between two tables.

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:

In RedBeanPHP, the underscore ‘_’ is used to denote a relationship between two tables. For example, the book_tag table is used to link books to tags.

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:

Have you ever read “Trees” (Trees and other poems) by Joyce Kilmer? It’s a beautiful poem about nature.

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();
28 April 2026

Indie developer and entrepreneur, founder of UXUI.media