|Updated

Introduction to Redbean

Share this article

Key Takeaways

  • Redbean is an ORM (Object Relational Mapper) that creates and modifies the underlying schema on-the-fly, making it ideal for prototyping and speeding up development time.
  • Redbean allows you to create an object or “bean” and save it to the database, adapting the schema to fit even if there isn’t a corresponding table.
  • Redbean supports relationships between objects, including one-to-one, one-to-many, and many-to-many, through the concept of “owning” related objects.
  • Redbean’s “fluid mode” allows for automatic adjustment of the database schema as objects change, but it is recommended to switch to “frozen mode” in production for performance and security reasons.
  • While Redbean is a great tool for prototyping and rapid iterations, it can also be used in production with careful steps such as reviewing column data types, foreign keys, relations, and indexes.

An Introduction to Redbean

When it comes to RAD and prototyping, there are lots of tools available to help get projects up-and-running quickly. From quick-starts to micro-frameworks, from build tools such as Composer to one-click installers, and of course ORMs – there are all sorts of ways to speed up development time. I’m going to look at Redbean, an ORM with a difference, which is ideal for prototyping.

Enter Redbean

Redbean is an ORM (Object Relational Mapper), but it does more than that – it creates and modifies the underlying schema on-the-fly. Traditionally, you would use an ORM as a wrapper to a pre-planned, pre-existing database schema. That’s fine for most projects, but when you’re prototyping – or making it up as you go along! – having it done for you behind the scenes can speed things up even more.

When you create an object with Redbean – or bean, to use the specific terminology – as soon as you save it to the database, the schema adapts itself to fit. This applies even if you’re trying to save an object without a corresponding table!

Installation

The easiest way to install Redbean is to download the all-in-one package. Then, you simply need to require the single file, rb.php.

You can also install it via Composer; however, the author of the library does not recommend this approach – see the installation page for details .

Dispensing

The first step when using Redbean is to “dispense” a bean – which is basically an object. Note that I’ll be using the term “bean” and object interchangeably throughout the rest of the post.

Dispensing is done via a static method of the overarching Redbean class, “R”, which takes the type as an argument.

For example:

$user = R::dispense('user');

This will create an empty object for a user, to which you can then assign properties. You can also dispense several at the same time by adding the number you want as a second parameter:

$users = R::dispense('user', 10);

It doesn’t matter at this stage whether there’s a table in the database to hold it; as soon as we try and store it, Redbean will take care of that.

Let’s try this – note the use of the static method store, which is used to write to the database:

$user->name = 'Joe Bloggs';
$user->email = 'joe.bloggs@example.com';
$id = R::store($user);
print $id;

In most ORM’s, you’d expect this to fail if you haven’t yet created a table to hold users. However, using Redbean this succeeds because it creates the table for you. If you take a look in your database at this stage, you should see a table like this:

user
----

id      int(11) UN PK AI
name    varchar(255)
email   varchar(255)

By necessity, the naming convention is pretty strict; it’s a singular, lower-case representation of the type you specified.

Now let’s look at how the schema changes as we iterate. A user record will likely need a password field – but we forgot to create one.

If you do this:

$user->password = 'secret';
R::store($user);

This time, Redbean knows how to store a user but there’s a new field that the database table can’t accommodate. No matter – it simply adds one, and your table will now look like this:

user
----

id          int(11) UN PK AI
name        varchar(255)
email       varchar(255)
password    varchar(255)

Field Data Types

Redbean tries to guess the data type of a field based on the information you provide. So if you did this:

$user->age = 30;
R::store($user);

You’ll find that the age field has been created as a tiny integer.

If a field type doesn’t prove sufficient later, Redbean simply alters it on-the-fly. If you tried to assign 3000 to the age now, the column would be changed to a normal integer. If you spelt out the name as “thirty”, it would be changed to a varchar. Set a varchar field to something greater than 255 characters and it becomes a TEXT field, and so on.

Finding Beans

You can load a specific object by primary key using load:

$user = R::load('user', 1);

You can load several objects at a time (by primary key) by using the batch method:

$users = R::batch('user', array(1, 2, 3));

This returns an array of beans.

You can also find beans using SQL. The second argument to the find method is essentially SQL from the WHERE clause onwards, excluding the WHERE keyword itself. For example, to find users who aren’t yet twenty:

$users = R::find('user', 'age < ?',
    array(20)
);

Note that we’re binding the parameters, hence the array as the third argument. This returns an array of beans using their ID’s as keys.

You can add more clauses to your SQL, for example:

$users = R::find('user', 'age < ? ORDER BY age ASC',
    array(20)
);

Counting

You can find out the number of records using the count method:

$number_of_users = R::count('user');

Deleting

To remove a single bean, use trash:

R::trash($user);

To remove more of a particular type, use trashAll:

R::trashAll('user');

To delete all beans of a particular type, use wipe:

R::wipe('user');

Or, to wipe out everything – which can be useful while prototyping – you nuke it:

R::nuke();

Relations

As with any ORM, relationships between objects are supported.

One-to-many relations are referred to using the concept of “owning” related objects. For example if orders have a single user, that user is said to “own” those orders. By using a specific variable name, we can build that relationship like this:

$orders = R::dispense('order', 2);
$orders[0]->order_id = '000001';
R::store($orders[0]);
$orders[1]->order_id = '000002';
R::store($orders[0]);

$user->ownOrders = $orders;
R::store($user);

The key element here is the property ownOrders. If you now inspect your database, you should find that Redbean has added the field user_id to the order table, along with a corresponding foreign key.

The user that “owns” the order can simply be accessed as a property, e.g.:

$user = $order->user;
print 'This order belongs to ' . $user->name;

In order to demonstrate many-to-many relationships, let’s create some roles:

$roles = R::dispense('role', 3);

$roles[0]->name = 'member';  
R::store($roles[0]);
$roles[1]->name = 'admin';  
R::store($roles[1]);
$roles[2]->name = 'super_admin';
R::store($roles[2]);

Roles don’t just belong to individual users; they are shared. So to assign the first two roles to a user, and in doing so build the relationship in the database, we can do this:

$roles = R::batch('user', array(1,2));
$user->sharedRole = $roles;
R::store($user);

This time, you should find a new table called role_user, which defines this relationship as a many-to-many.

You can get the roles belonging to a user by reading the property:

$roles = $user->sharedRole;

This lazy-loads the roles the first time they’re accessed.

There’s a lot more to relationships, including the ability to add properties to the relation using link, filtering by link, eager loading, and so on – check out the documentation for details.

Models

You can create models to correspond to bean types simply by following naming certain conventions. Models are then connected to beans using FUSE; as in, by following the relevant naming convention they are FUSEd together.

The convention is simple; separate “Model” and the type with an underscore, e.g. Model_Type. So for example, to create a model for users, you simply do this:

class Model_User extends RedBean_SimpleModel { }

Once you’ve defined a model, there are a number of methods you can implement which will get called at different points in the bean’s lifecycle. This is illustrated in the table below, which maps the CRUD operations to the “hooks” you can implement:

R::store        $model->update()
R::store        $model->after_update()
R::load            $model->open()
R::trash        $model->delete()
R::trash        $model->after_delete()
R::dispense        $model->dispense()

So, for example, you could add validation by implementing update():

class Model_User extends RedBean_SimpleModel { 
  public function update() {
    if (strlen($this->password) < 8) {
      throw new Exception('Password must be at least 8 characters long');
    }
  }
}

You can also create your own methods, of course, as well as custom GETters.

Querying the Database

You can execute a raw SQL query like this:

R::exec('UPDATE user SET status = 1');

You can return a multidimensional array of rows like this:

R::getAll('SELECT * FROM user');

Additionally, you can use parameter binding:

R::getAll('SELECT * FROM user WHERE status = :status',
    array(':status' => 1)
);

You can fetch a single column like this:

R::getCol('SELECT email FROM user');

You can also get an associative array using two columns of a table like so:

R::$adapter->getAssoc('SELECT id, email FROM user');

Deploying your Application

Although it’s arguably best suited for prototyping – or at least development – there’s no reason you can’t continue your use of Redbean into production, provided you follow certain steps.

Redbean’s mechanism for updating the schema on-the-fly is called “fluid mode”; however this isn’t appropriate for production, and has a pretty significant performance overhead. However, you can turn it off by “freezing” it:

R::freeze( true );

In going into production, you’re going to want to follow a few more steps:

  • review the column data types
  • review the foreign keys and relations
  • check the indexes – Redbean creates a few – and modify appropriately

Summary

In this article, I’ve introduced Redbean as a handy way to kick-start your development process, by allowing you to play around with your domain models without worrying about building the underlying schema first. Whether it’s viable for production remains to be seen – but for prototyping and rapid iterations, it’s a great little tool. There’s much I haven’t covered, so be sure to check out the documentation.

Frequently Asked Questions (FAQs) about RedBeanPHP

What are the key features of RedBeanPHP?

RedBeanPHP is a simple, lightweight Object Relational Mapping (ORM) tool that offers a range of features designed to simplify database interactions. It is known for its “zero-config” approach, meaning it requires minimal setup and configuration. It automatically builds your database schema based on the objects you create, and it can adjust the schema as needed when your objects change. RedBeanPHP also supports fluid and frozen modes, allowing you to switch between development and production environments easily. It includes built-in tree structures and supports bean canning and dispensing for easy storage and retrieval of objects.

How does RedBeanPHP compare to other ORM tools?

Compared to other ORM tools, RedBeanPHP stands out for its simplicity and ease of use. It requires no configuration files, no SQL, and no model classes. This makes it a great choice for beginners or for projects where a full-featured ORM would be overkill. However, it still offers powerful features like automatic schema modification and tree structures, making it versatile enough for more complex projects as well.

How do I install and set up RedBeanPHP?

RedBeanPHP can be installed via Composer, a popular dependency management tool for PHP. Once installed, you can set up RedBeanPHP by including the RedBeanPHP file in your script and setting up a database connection. RedBeanPHP will automatically create and modify tables as needed based on your objects.

What is the “fluid mode” in RedBeanPHP?

Fluid mode is a feature of RedBeanPHP that allows it to automatically adjust your database schema as your objects change. This can be a huge time-saver during development, as you don’t have to manually modify your database every time you make a change to your objects. However, it’s recommended to switch to “frozen mode” in production for performance and security reasons.

How does RedBeanPHP handle relationships between objects?

RedBeanPHP supports several types of relationships between objects, including one-to-one, one-to-many, and many-to-many. These relationships are handled through the use of “beans”, which are simple objects that represent rows in a database table. You can easily associate beans with each other to represent relationships between objects.

Can I use RedBeanPHP with my existing database?

Yes, RedBeanPHP can be used with an existing database. However, it’s important to note that RedBeanPHP’s automatic schema modification features may make changes to your database structure, so it’s recommended to back up your database before using RedBeanPHP.

Is RedBeanPHP suitable for large, complex projects?

While RedBeanPHP is known for its simplicity and ease of use, it also offers powerful features that make it suitable for larger, more complex projects. Its automatic schema modification, support for various types of relationships, and built-in tree structures can all be valuable in a larger project. However, for very large or complex projects, a more full-featured ORM tool may be more appropriate.

How does RedBeanPHP handle security?

RedBeanPHP includes several features designed to enhance security. It uses prepared statements to help prevent SQL injection attacks, and it recommends using “frozen mode” in production to prevent unwanted schema changes. However, as with any tool, it’s important to follow best practices for security and to keep RedBeanPHP up to date.

What is “bean canning” in RedBeanPHP?

Bean canning is a feature of RedBeanPHP that allows you to store and retrieve entire sets of beans (objects) at once. This can be a convenient way to handle large amounts of data, and it can also help to improve performance by reducing the number of database queries.

Can I use RedBeanPHP without Composer?

While Composer is the recommended way to install RedBeanPHP, it’s also possible to download and include the RedBeanPHP file directly in your script. However, using Composer can make it easier to manage and update RedBeanPHP and any other dependencies your project may have.

Lukas WhiteLukas White
View Author

Lukas is a freelance web and mobile developer based in Manchester in the North of England. He's been developing in PHP since moving away from those early days in web development of using all manner of tools such as Java Server Pages, classic ASP and XML data islands, along with JavaScript - back when it really was JavaScript and Netscape ruled the roost. When he's not developing websites and mobile applications and complaining that this was all fields, Lukas likes to cook all manner of World foods.

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week