Welcome

Less Suitable Projects

  • Existing applications with custom database (use Propel instead)
  • Hi-traffic distributed content apps, i.e. the next Twitter… (use a NoSQL database like Cassandra)
  • Project requiring serious use of UUIDs/GUIDs. While RedBeanPHP offers basic read support for UUIDs, this is probably not sufficient.

You should also NOT use RedBeanPHP if you don’t like the RedBeanPHP schema policies and you want complete control over the layout of your database schema, i.e. the column names used for primary keys and foreign keys. In this case I recommend to use: Doctrine. If Doctrine is too big for your taste you might also consider a small, active record like ORM written by a friend of mine: DicaORM.

back to main menu


Step 6: Playing with models

Just for fun, we’re going to add a model. In many web application using the MVC pattern, models are used to encapsulate the business rules. Now let’s say we don’t accept tasting notes containing less than four characters. This qualifies as a business rule in the drinking business :). To add this validation rule we need to have a model. In most object relational mappers this is why you have to create a whole class first. In RedBeanPHP we like to things a little different. We have no models remember? Just beans. So, how do we go from a bean to a model ? Simple, we just add a model and RedBeanPHP will automatically detect its presence. Based on the naming convention it will connect the model to the bean. Here we go:

Within the note model we can refer to our bean using:

The update() method will be invoked by the bean once we try to store it. There is no way to stop the code flow though, to prevent RedBeanPHP from storing the bean we have to throw an exception, or issue a die() statement. Let’s test it:

php dram.php --attach-to=4 --note="ap" Note is too short!

Nice! That works really well! See? We did not have to change our code, simply add models whenever you like. No need to take all your code, put it in a class or add validation rules here and there, no, just add the model and suddenly all actions will flow through it. Besides update() we can use a lot of other ‘hooks’ to do all sorts of model stuff.

RedBeanPHP

  • Getting started
    • Welcome
    • Quick tour
    • System Requirements
    • Installing
    • Setup
    • Connect
  • Basics
    • Create a Bean
    • Loading a Bean
    • Deleting a Bean
    • Freeze
  • Finding
    • Finding Beans
    • Queries
    • Mixing SQL and PHP
  • Relation Mapping
    • One-to-many
    • Many-to-many
    • Parent Object
    • Counting beans
    • Eager loading
    • Aliasing
    • Trees
    • Enums and more
    • Tags
    • Cheatsheet
  • Models
    • Adding Models
    • FUSE
    • Custom Methods
    • Dependency Injection
  • Database
    • Schema
    • Multiple databases
    • Transactions
    • Nuke
  • Advanced
    • Association API
    • Copy Beans
    • Import and Export
    • Debug and log
    • Meta Data
    • Labels
    • Cooker
    • Cache
    • Internals
  • Project
    • FAQ
    • Roadmap
    • Branches and Versions
    • Beta Testing
    • Changelog
    • Upgrade
    • Plugins
    • License
    • Credits
  • Tools
    • Replica
    • BeanCan Server
    • REST server
    • Namespacer
    • RedUNIT
    • Archive

Writing a new Query Writer

To add a new, custom Query Writer for your favourite RDBMS simply wrap the writer in a plugin. To activate your writer people should issue the following command:

The reason for this is that it is too hard for me to maintain all writers in the core, especially writers for commercial database platform I can’t even obtain. Therefore they are separated from the core and hosted in their own repositories by the contributors. Query Writer authors can make the plugins available using the setup-approach described above. Note that this is also more flexible as it allows a database writer plugin to select a different driver (OCI instead of PDO for instance) or maybe even a different toolbox. Query writers should implement all methods defined in the Query Writer interface (see API). Many methods are already implemented in the Abstract Query Writer, these can be reused if they are appropriate for the new Query Writer as well.

FAQ

Why do you use so much static functions? What about coupling?

That’s only the Facade. Behind the facade you will find a landscape of elegant classes, see the API for advanced usage/more information. The API closely resembles the interface of the facade class.

Is it wrong to use the static facade functions?

If you’re not planning to swap frameworks regularly you can rely on the easy-to-use static facade functions like R::dispense() and R::load() etc. People often complain about static methods but in reality many of those so-called pure OOP style projects tend to become heaps of powerless miniature objects and countless wirings. I don’t believe that works very well.

Why is RedBeanPHP one file? Isn’t that bad practice?

RedBeanPHP is distributed as one file to ease installation and deployment. The build script called Replica compiles the RedBeanPHP class files to one file. So in reality, RedBeanPHP is not one file, read more about Replica.

Why don’t you implement my feature request?

Depends. RedBeanPHP is being developed in a very careful way. I try to keep RedBeanPHP clean yet comfortable. It’s tempting to implement lots of features but that would make RedBeanPHP bloated. Feel free to write your own plugin or fork the project.

Why does RedBeanPHP not support custom table mapping (anymore)?

The idea of RedBeanPHP is to generate a useable and queryable schema based on your code and without any configuration. Custom table mappings don’t fit very well in this model. However there are other reasons as well. Many so called power features like deep-copy have to make assumptions about database layout and table naming conventions. They can of course use some kind of configuration file to figure things out, but hey the whole idea of RedBeanPHP was NOT to use configuration! In the past RedBeanPHP had a bean formatter for custom mappings, this functionality does not exist anymore. If you still require custom mappings, for instance to use RedBeanPHP with existing schemas you might want to try to use VIEWS. Simply map the views to your tables. If you only change table names and column names your views can be used for updates as well. Although not a perfect solution we have received some positive feedback about this approach.

Why does RedBeanPHP not provide a portable query language?

I do not believe in portable query languages or database independent query builders. The whole point of selecting a database is to choose the system that provides the most useful features. A portable query language by definition can’t use database specific features, so you simply get the worst of all. Just dare to choose your the database system that fits the best for the task at hand.

Why are underscores and uppercase chars not allowed in type and property names?

Underscores ARE allowed in property names, just not in type names. RedBeanPHP uses underscores to denote relationships among beans. Uppercase characters cause problems on different operating system platforms. These characters have one further disadvantage; because programmers like me are often lazy, they get overused to form ambiguous words. The English vocabulary is quite big and you should better be creative and find the best word for the concept your bean or model describes. For instance; instead of «user_project» or «ProjectUsr» you can use «participant». This makes your database prettier and easier to read as well.

Step 1: Setup

First, we need to download and install the RedBeanPHP package. Luckily, this is a no-brainer. RedBeanPHP is distributed as a single file which we just grab from the internet like this:

url=http://www.redbeanphp.com/downloadredbean.php wget $url --output-document="redbeanphp.tar.gz" tar xvf redbeanphp.tar.gz

Here we download the RedBeanPHP package from the RedBeanPHP servers. We then extract the contents of the tarball. RedBeanPHP is always distributed as a single tarball containing the single code file. The code file inside the tarball is named:

rb.php

For this tutorial, we’ll use a temporary database, so after rebooting your system, the data will be gone. While not very practical in real life, this is ideal for testing and playing with RedBeanPHP. So, let’s create our application, the dram.php file:

touch dram.php

…and we’re going to edit it using our favourite editor…

vim dram.php

I like to use VIM but that’s of course just a matter of choice. Any plaintext editor would do fine of course. Now, let’s require the RedBeanPHP library file and setup our database connection:

That’s all, we’re now ready to start coding now.

Query parameters

By default, the debugger prints the queries and parameters in separate sections. Sometimes you might prefer to see what the actual query would look like if the parameters had been filled in. RedBeanPHP 4.1+ offers two new debugger modes to facilitate this:


Outputs the query above like this:

INSERT INTO "event" ( id, "name" ) VALUES ( NULL, "party" )

Mode 2 also writes to the logs, if you want to suppress screen output, select mode 3.

In ‘fancy’ mode schema altering queries are highlighted as well as bound parameters. Parameter bindings are also included in the SQL instead of in a separate list. If a parameter value is too long, fancy debug will only show the first part so your query remains readable. Also, fancy debug works with HTML colors as well, in case you like to debug with a browser instead of a command line.

Step 2: Let’s add a bottle of whisky

When working with RedBeanPHP, it’s important to start by creating records first. So first write your logic for adding records to the database. Some people like to begin by creating an overview page listing all the records in a table, however this means your database must already contain at least some data. Since we like RedBeanPHP to do all the heavy lifting for us, including table and column creation, we better start the other way around, by adding records. So, always start with your ‘add’ code.

We use the getopt() function of PHP to read commands from the console. In this case we listen for two commands: add and list. Now let’s see how we add a bottle of whisky to our collection:

This code works very simple: it takes the value of the add parameter from the command line and creates a new bean of type whisky. It then puts the text in the name property of the bean and stores it. To make it possible for our users to view the whisky menu we also implement a list feature:

We can now use the application like this:

php dram.php --add="Bowmore 12yo" OK. php dram.php --add="Lagavulin 16yo" OK.

…and to view the list…

php dram.php --list * #1: Bowmore 12yo * #2: Lagavulin 16yo

That’s already quite a fancy application in just a couple of lines. But we can do more! However, before we continue, let’s take a look at the database. Before we began, it was empty, but now we see this:

geek@beans$ sqlite3 /tmp/red.db SQLite version 3.7.13 2025-06-11 02:05:22 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> .tables whisky

We see the whisky table has been created. The required columns are there as well:

sqlite> .schema CREATE TABLE `whisky` ( id INTEGER PRIMARY KEY AUTOINCREMENT , `name` TEXT );

RedBeanPHP creates the necessary tables and columns automatically. The type of the column in the database depends on the value you want to store in it. RedBeanPHP scans the value you want to store in a column and makes sure the column has a type that can contain your data properly. You can always tune your database schema manually of course.

Verify your download

Here are the sha256sum outputs of the files:

7ef9b9a680854ecd6039480007ed8236aec81acd3f188790e0ae5bba5c312a3e  RedBeanPHP5_5-mysql.tgz
6370ff09132bee8b1fc2fc3a65b79ccb1f40d4d9df5f51b4ad227ba6adc9a79d  RedBeanPHP5_5-postgres.tgz
f47ed6be8cbecd918aa9287895fa6de1827a0b7ed5563ac4bc7b3f281d9fec8a  RedBeanPHP5_5-sqlite.tgz
a4603c7812852737df7c1e33ecd4c26f9b77b26b19a614f3798521bf35149d8b  RedBeanPHP5_5.tgz
signify key: 
untrusted comment: signify public key
RWSEPjwPrf4jAtahiV/HNXWz83QYsppKn0EzVOhsoVV24gwB6mGpsdXL

Always make sure you check the sha256sum before including the file.

If you use PHP 5.3.3 or older, run the first. Download the P533-patch for old PHP versions.

Major version

When the major version number increases, this means the new version is NOT backward compatible with all previous versions. Most of the time this means you better not use it in your current project if you are already using RedBeanPHP or you might have to make some changes to the project to make it work with the new version of RedBeanPHP. This is not always as bad as it sounds. For instance version 3 is not backward compatible with version 2, but only if you use the optimizers (which by default are turned off). So while this is a major version bump it’s actually not that bad. However, while difference between 2 and 3 is relatively small, the gap between 1 and 2 was a really big one. Anyway whenever the major version number changes make sure you check the changelog to determine whether you can upgrade or not.

RedBeanPHP

  • Getting started
    • Welcome
    • Quick tour
    • System Requirements
    • Installing
    • Setup
    • Connect
  • Basics
    • Create a Bean
    • Loading a Bean
    • Deleting a Bean
    • Freeze
  • Finding
    • Finding Beans
    • Queries
    • Mixing SQL and PHP
  • Relation Mapping
    • One-to-many
    • Many-to-many
    • Parent Object
    • Counting beans
    • Eager loading
    • Aliasing
    • Trees
    • Enums and more
    • Tags
    • Cheatsheet
  • Models
    • Adding Models
    • FUSE
    • Custom Methods
    • Dependency Injection
  • Database
    • Schema
    • Multiple databases
    • Transactions
    • Nuke
  • Advanced
    • Association API
    • Copy Beans
    • Import and Export
    • Debug and log
    • Meta Data
    • Labels
    • Cooker
    • Cache
    • Internals
  • Project
    • FAQ
    • Roadmap
    • Branches and Versions
    • Beta Testing
    • Changelog
    • Upgrade
    • Plugins
    • License
    • Credits
  • Tools
    • Replica
    • BeanCan Server
    • REST server
    • Namespacer
    • RedUNIT
    • Archive

Conversion table

Here is a kind of conversion table to look up R-methods and find the corresponding methods on objects behind the facade.

R::method() Class and Method Description
1In fluid mode the facade suppresses table/column not found exceptions.
2If you pass a base bean (3rd param) facade will use RedBean_AssociationManager_ExtAssociationManager.
3Facade ignores these calls in fluid mode (to avoid exceptions in some DB systems).
4Be careful, Facade ignores this method in Frozen mode!
5SQLHelper constructor requires only the Adapter, not the entire toolbox.
R::dispense RedBean_OODB : dispense Dispense a bean
R::load RedBean_OODB : load Load a bean
R::store RedBean_OODB : store Store a bean
R::trash RedBean_OODB : trash Delete a bean
R::find RedBean_Finder : find Finds a bean
R::exec RedBean_Adapter_DBAdapter : exec Executes SQL
R::getAll RedBean_Adapter_DBAdapter : get Query the database
R::dup RedBean_DuplicationManager : setFilters, dup Duplicate a bean
R::exportAll RedBean_DuplicationManager : exportAll Export beans
R::associate RedBean_AssociationManager : associate Associate two beans
R::tag RedBean_TagManager : tag Tag a bean
R::related RedBean_AssociationManager : relatedSimple Retrieve related beans
R::commit RedBean_Adapter_DBAdapter : commit Commits transaction
R::begin RedBean_Adapter_DBAdapter : startTransaction Begins transaction
R::rollback RedBean_Adapter_DBAdapter : rollback Rolls back a transaction
R::nuke RedBean_QueryWriter : wipeAll Destroys database
R::dependencies RedBean_OODB : setDepList Sets dependent beans
R::getColumns RedBean_QueryWriter : getColumns List columns of a table
R::genSlots RedBean_SQLHelper : genSlots Generates slots
R::freeze RedBean_OODB : freeze Freezes the schema

Note that R::dup() first sets filters (if any) and then calls the dup() method on the Duplication Manager service object.

No Configuration

Most ORMs use configuration files (XML, INI or YAML) or some sort of annotation system to define mappings. These systems force you to map records to objects upfront. RedBeanPHP is different. Instead of using configuration it uses conventions; a very small set of rules. RedBeanPHP uses these conventions to infer relationships and to automate mappings. RedBeanPHP also helps you to follow these conventions by automatically building the initial tables and columns for you — which also saves a lot of time. This means there is no configuration, less boilerplate code and more time left to focus on the business logic, testing and documentation, thus boosting development productivity and code quality.

Dispense multiple beans

To dispense multiple beans at once:

RedBeanPHP 3.5 offers even more comfort for lazy developers:

Start your code with: R::useWriterCache(true); to make use of query caching. This will prevent RedBeanPHP from performing unnecessary queries. This feature is available since RedBeanPHP 3.4. While RedBeanPHP offers other caching mechanisms as well this is the easiest to use and it’s completely transparent!

Bean types may only consist of lowercase alphanumeric symbols a-z and 0-9 (no underscores). A property name has to begin with a letter and may consists of letters and numbers. Underscores in property names are allowed but I recommend to come up with better nouns instead. Underscores in Bean types are not allowed because RedBeanPHP uses these to identify relations. Underscores are used to denote a relation between two beans, therefore you should not dispense such beans yourself. The RedBeanPHP naming restrictions allow RedBeanPHP to figure out relationships among tables and beans without configuration; however these rules also help you to maintain a clean and consistent database schema. Moreover, developers often make up terrible names for tables (i.e. ‘tbl_userrights’, ‘person_Project’ etc…). I try to encourage people to take some time to find the correct ‘name’ (often a simple noun) for their beans (i.e. ‘privilege’,’participant’). This also improves the readability (and maintainability) of your database. Just take some time to find the noun that describes the entity you’re modelling best. If, for some reason you really need to break these rules use: Use R::setStrictTyping(false); This may cause some side effects with dup() and export() though.

As of RedBeanPHP 3.4, a property name like ‘singleMalt’ will be automatically converted to ‘single_malt’. If you don’t like that, use: RedBean_OODBBean::setFlagBeautifulColumnNames(false);

RedBeanPHP 5.4 (1 October 2019, St. Nicholas Edition)

  • Debug Logger now correctly handles typed bindings (author AbygailG)
  • R::store( $beans, ); (author Gabor, inspiration from PR David Sickmiller)
  • R::storeAll( $beans, );
  • R::findForUpdate() (author Gabor)
  • R::traverse(…,function( ,$depth){}) passes depth level (author Lynesth)
  • Allow findLike (and the likes) to use «IS NULL» conditions (author Lynesth)
  • Have trash/trashAll return number of deleted beans (author Lynesth)
  • Fixed Facade::removeToolBoxByKey removing the toolbox (thanks Dmelo)
  • R::getRow() now adheres to return type array (author Nucc1)
  • R::setAllowFluidTransactions() (thanks Lynesth and Marios88)
  • Peformance improvement of R::diff() (author Lynesth)
  • Fix Cache prevent a second FOR-UPDATE SQL query (author Gabor)
  • Additional unit tests
  • Improvement source code documentation

RedBeanPHP

  • Getting started
    • Welcome
    • Quick tour
    • System Requirements
    • Installing
    • Setup
    • Connect
  • Basics
    • Create a Bean
    • Loading a Bean
    • Deleting a Bean
    • Freeze
  • Finding
    • Finding Beans
    • Queries
    • Mixing SQL and PHP
  • Relation Mapping
    • One-to-many
    • Many-to-many
    • Parent Object
    • Counting beans
    • Eager loading
    • Aliasing
    • Trees
    • Enums and more
    • Tags
    • Cheatsheet
  • Models
    • Adding Models
    • FUSE
    • Custom Methods
    • Dependency Injection
  • Database
    • Schema
    • Multiple databases
    • Transactions
    • Nuke
  • Advanced
    • Association API
    • Copy Beans
    • Import and Export
    • Debug and log
    • Meta Data
    • Labels
    • Cooker
    • Cache
    • Internals
  • Project
    • FAQ
    • Roadmap
    • Branches and Versions
    • Beta Testing
    • Changelog
    • Upgrade
    • Plugins
    • License
    • Credits
  • Tools
    • Replica
    • BeanCan Server
    • REST server
    • Namespacer
    • RedUNIT
    • Archive

Point version

A point version or point release happens when the last digit has been increased. Note that although you might assume a digit normally varies from 0-9, you might encounter minor and point releases like X.X.12 or X.30.X. Not sure if this will happen, however as RedBeanPHP matures you will see less major upgrades and more minor upgrades and point releases. A point release version is normally a maintenance version. This may include bugfixes, new tests, documentation changes or just some code cleanup. While it’s always a good idea to scan the changelog most of the time you can be pretty sure there are no compatibility issues nor interesting new feature. Of course if you have reported an issue the point release can be quite interesting because the bug might have been fixed. In this case, the Github bug report number and the fix will be mentioned in the changelog.


back to main menu


Less Suitable Projects

  • Existing applications with custom database (use Propel instead)
  • Hi-traffic distributed content apps, i.e. the next Twitter… (use a NoSQL database like Cassandra)
  • Project requiring serious use of UUIDs/GUIDs. While RedBeanPHP offers basic read support for UUIDs, this is probably not sufficient.

You should also NOT use RedBeanPHP if you don’t like the RedBeanPHP schema policies and you want complete control over the layout of your database schema, i.e. the column names used for primary keys and foreign keys. In this case I recommend to use: Doctrine. If Doctrine is too big for your taste you might also consider a small, active record like ORM written by a friend of mine: DicaORM.

back to main menu

Step 6: Playing with models

Just for fun, we’re going to add a model. In many web application using the MVC pattern, models are used to encapsulate the business rules. Now let’s say we don’t accept tasting notes containing less than four characters. This qualifies as a business rule in the drinking business :). To add this validation rule we need to have a model. In most object relational mappers this is why you have to create a whole class first. In RedBeanPHP we like to things a little different. We have no models remember? Just beans. So, how do we go from a bean to a model ? Simple, we just add a model and RedBeanPHP will automatically detect its presence. Based on the naming convention it will connect the model to the bean. Here we go:

Within the note model we can refer to our bean using:

The update() method will be invoked by the bean once we try to store it. There is no way to stop the code flow though, to prevent RedBeanPHP from storing the bean we have to throw an exception, or issue a die() statement. Let’s test it:

php dram.php --attach-to=4 --note="ap" Note is too short!

Nice! That works really well! See? We did not have to change our code, simply add models whenever you like. No need to take all your code, put it in a class or add validation rules here and there, no, just add the model and suddenly all actions will flow through it. Besides update() we can use a lot of other ‘hooks’ to do all sorts of model stuff.

RedBeanPHP

  • Getting started
    • Welcome
    • Quick tour
    • System Requirements
    • Installing
    • Setup
    • Connect
  • Basics
    • Create a Bean
    • Loading a Bean
    • Deleting a Bean
    • Freeze
  • Finding
    • Finding Beans
    • Queries
    • Mixing SQL and PHP
  • Relation Mapping
    • One-to-many
    • Many-to-many
    • Parent Object
    • Counting beans
    • Eager loading
    • Aliasing
    • Trees
    • Enums and more
    • Tags
    • Cheatsheet
  • Models
    • Adding Models
    • FUSE
    • Custom Methods
    • Dependency Injection
  • Database
    • Schema
    • Multiple databases
    • Transactions
    • Nuke
  • Advanced
    • Association API
    • Copy Beans
    • Import and Export
    • Debug and log
    • Meta Data
    • Labels
    • Cooker
    • Cache
    • Internals
  • Project
    • FAQ
    • Roadmap
    • Branches and Versions
    • Beta Testing
    • Changelog
    • Upgrade
    • Plugins
    • License
    • Credits
  • Tools
    • Replica
    • BeanCan Server
    • REST server
    • Namespacer
    • RedUNIT
    • Archive

Writing a new Query Writer

To add a new, custom Query Writer for your favourite RDBMS simply wrap the writer in a plugin. To activate your writer people should issue the following command:

The reason for this is that it is too hard for me to maintain all writers in the core, especially writers for commercial database platform I can’t even obtain. Therefore they are separated from the core and hosted in their own repositories by the contributors. Query Writer authors can make the plugins available using the setup-approach described above. Note that this is also more flexible as it allows a database writer plugin to select a different driver (OCI instead of PDO for instance) or maybe even a different toolbox. Query writers should implement all methods defined in the Query Writer interface (see API). Many methods are already implemented in the Abstract Query Writer, these can be reused if they are appropriate for the new Query Writer as well.

FAQ

Why do you use so much static functions? What about coupling?

That’s only the Facade. Behind the facade you will find a landscape of elegant classes, see the API for advanced usage/more information. The API closely resembles the interface of the facade class.

Is it wrong to use the static facade functions?

If you’re not planning to swap frameworks regularly you can rely on the easy-to-use static facade functions like R::dispense() and R::load() etc. People often complain about static methods but in reality many of those so-called pure OOP style projects tend to become heaps of powerless miniature objects and countless wirings. I don’t believe that works very well.

Why is RedBeanPHP one file? Isn’t that bad practice?

RedBeanPHP is distributed as one file to ease installation and deployment. The build script called Replica compiles the RedBeanPHP class files to one file. So in reality, RedBeanPHP is not one file, read more about Replica.

Why don’t you implement my feature request?

Depends. RedBeanPHP is being developed in a very careful way. I try to keep RedBeanPHP clean yet comfortable. It’s tempting to implement lots of features but that would make RedBeanPHP bloated. Feel free to write your own plugin or fork the project.

Why does RedBeanPHP not support custom table mapping (anymore)?

The idea of RedBeanPHP is to generate a useable and queryable schema based on your code and without any configuration. Custom table mappings don’t fit very well in this model. However there are other reasons as well. Many so called power features like deep-copy have to make assumptions about database layout and table naming conventions. They can of course use some kind of configuration file to figure things out, but hey the whole idea of RedBeanPHP was NOT to use configuration! In the past RedBeanPHP had a bean formatter for custom mappings, this functionality does not exist anymore. If you still require custom mappings, for instance to use RedBeanPHP with existing schemas you might want to try to use VIEWS. Simply map the views to your tables. If you only change table names and column names your views can be used for updates as well. Although not a perfect solution we have received some positive feedback about this approach.

Why does RedBeanPHP not provide a portable query language?

I do not believe in portable query languages or database independent query builders. The whole point of selecting a database is to choose the system that provides the most useful features. A portable query language by definition can’t use database specific features, so you simply get the worst of all. Just dare to choose your the database system that fits the best for the task at hand.

Why are underscores and uppercase chars not allowed in type and property names?

Underscores ARE allowed in property names, just not in type names. RedBeanPHP uses underscores to denote relationships among beans. Uppercase characters cause problems on different operating system platforms. These characters have one further disadvantage; because programmers like me are often lazy, they get overused to form ambiguous words. The English vocabulary is quite big and you should better be creative and find the best word for the concept your bean or model describes. For instance; instead of «user_project» or «ProjectUsr» you can use «participant». This makes your database prettier and easier to read as well.

Step 1: Setup

First, we need to download and install the RedBeanPHP package. Luckily, this is a no-brainer. RedBeanPHP is distributed as a single file which we just grab from the internet like this:

url=http://www.redbeanphp.com/downloadredbean.php wget $url --output-document="redbeanphp.tar.gz" tar xvf redbeanphp.tar.gz

Here we download the RedBeanPHP package from the RedBeanPHP servers. We then extract the contents of the tarball. RedBeanPHP is always distributed as a single tarball containing the single code file. The code file inside the tarball is named:

rb.php

For this tutorial, we’ll use a temporary database, so after rebooting your system, the data will be gone. While not very practical in real life, this is ideal for testing and playing with RedBeanPHP. So, let’s create our application, the dram.php file:

touch dram.php

…and we’re going to edit it using our favourite editor…

vim dram.php

I like to use VIM but that’s of course just a matter of choice. Any plaintext editor would do fine of course. Now, let’s require the RedBeanPHP library file and setup our database connection:

That’s all, we’re now ready to start coding now.

Query parameters

By default, the debugger prints the queries and parameters in separate sections. Sometimes you might prefer to see what the actual query would look like if the parameters had been filled in. RedBeanPHP 4.1+ offers two new debugger modes to facilitate this:

Outputs the query above like this:

INSERT INTO "event" ( id, "name" ) VALUES ( NULL, "party" )

Mode 2 also writes to the logs, if you want to suppress screen output, select mode 3.

In ‘fancy’ mode schema altering queries are highlighted as well as bound parameters. Parameter bindings are also included in the SQL instead of in a separate list. If a parameter value is too long, fancy debug will only show the first part so your query remains readable. Also, fancy debug works with HTML colors as well, in case you like to debug with a browser instead of a command line.

Step 2: Let’s add a bottle of whisky

When working with RedBeanPHP, it’s important to start by creating records first. So first write your logic for adding records to the database. Some people like to begin by creating an overview page listing all the records in a table, however this means your database must already contain at least some data. Since we like RedBeanPHP to do all the heavy lifting for us, including table and column creation, we better start the other way around, by adding records. So, always start with your ‘add’ code.

We use the getopt() function of PHP to read commands from the console. In this case we listen for two commands: add and list. Now let’s see how we add a bottle of whisky to our collection:

This code works very simple: it takes the value of the add parameter from the command line and creates a new bean of type whisky. It then puts the text in the name property of the bean and stores it. To make it possible for our users to view the whisky menu we also implement a list feature:

We can now use the application like this:

php dram.php --add="Bowmore 12yo" OK. php dram.php --add="Lagavulin 16yo" OK.

…and to view the list…

php dram.php --list * #1: Bowmore 12yo * #2: Lagavulin 16yo

That’s already quite a fancy application in just a couple of lines. But we can do more! However, before we continue, let’s take a look at the database. Before we began, it was empty, but now we see this:

geek@beans$ sqlite3 /tmp/red.db SQLite version 3.7.13 2025-06-11 02:05:22 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> .tables whisky

We see the whisky table has been created. The required columns are there as well:

sqlite> .schema CREATE TABLE `whisky` ( id INTEGER PRIMARY KEY AUTOINCREMENT , `name` TEXT );

RedBeanPHP creates the necessary tables and columns automatically. The type of the column in the database depends on the value you want to store in it. RedBeanPHP scans the value you want to store in a column and makes sure the column has a type that can contain your data properly. You can always tune your database schema manually of course.

Verify your download

Here are the sha256sum outputs of the files:

7ef9b9a680854ecd6039480007ed8236aec81acd3f188790e0ae5bba5c312a3e  RedBeanPHP5_5-mysql.tgz
6370ff09132bee8b1fc2fc3a65b79ccb1f40d4d9df5f51b4ad227ba6adc9a79d  RedBeanPHP5_5-postgres.tgz
f47ed6be8cbecd918aa9287895fa6de1827a0b7ed5563ac4bc7b3f281d9fec8a  RedBeanPHP5_5-sqlite.tgz
a4603c7812852737df7c1e33ecd4c26f9b77b26b19a614f3798521bf35149d8b  RedBeanPHP5_5.tgz
signify key: 
untrusted comment: signify public key
RWSEPjwPrf4jAtahiV/HNXWz83QYsppKn0EzVOhsoVV24gwB6mGpsdXL

Always make sure you check the sha256sum before including the file.

If you use PHP 5.3.3 or older, run the first. Download the P533-patch for old PHP versions.

Major version

When the major version number increases, this means the new version is NOT backward compatible with all previous versions. Most of the time this means you better not use it in your current project if you are already using RedBeanPHP or you might have to make some changes to the project to make it work with the new version of RedBeanPHP. This is not always as bad as it sounds. For instance version 3 is not backward compatible with version 2, but only if you use the optimizers (which by default are turned off). So while this is a major version bump it’s actually not that bad. However, while difference between 2 and 3 is relatively small, the gap between 1 and 2 was a really big one. Anyway whenever the major version number changes make sure you check the changelog to determine whether you can upgrade or not.

RedBeanPHP

  • Getting started
    • Welcome
    • Quick tour
    • System Requirements
    • Installing
    • Setup
    • Connect
  • Basics
    • Create a Bean
    • Loading a Bean
    • Deleting a Bean
    • Freeze
  • Finding
    • Finding Beans
    • Queries
    • Mixing SQL and PHP
  • Relation Mapping
    • One-to-many
    • Many-to-many
    • Parent Object
    • Counting beans
    • Eager loading
    • Aliasing
    • Trees
    • Enums and more
    • Tags
    • Cheatsheet
  • Models
    • Adding Models
    • FUSE
    • Custom Methods
    • Dependency Injection
  • Database
    • Schema
    • Multiple databases
    • Transactions
    • Nuke
  • Advanced
    • Association API
    • Copy Beans
    • Import and Export
    • Debug and log
    • Meta Data
    • Labels
    • Cooker
    • Cache
    • Internals
  • Project
    • FAQ
    • Roadmap
    • Branches and Versions
    • Beta Testing
    • Changelog
    • Upgrade
    • Plugins
    • License
    • Credits
  • Tools
    • Replica
    • BeanCan Server
    • REST server
    • Namespacer
    • RedUNIT
    • Archive

Conversion table

Here is a kind of conversion table to look up R-methods and find the corresponding methods on objects behind the facade.

R::method() Class and Method Description
1In fluid mode the facade suppresses table/column not found exceptions.
2If you pass a base bean (3rd param) facade will use RedBean_AssociationManager_ExtAssociationManager.
3Facade ignores these calls in fluid mode (to avoid exceptions in some DB systems).
4Be careful, Facade ignores this method in Frozen mode!
5SQLHelper constructor requires only the Adapter, not the entire toolbox.
R::dispense RedBean_OODB : dispense Dispense a bean
R::load RedBean_OODB : load Load a bean
R::store RedBean_OODB : store Store a bean
R::trash RedBean_OODB : trash Delete a bean
R::find RedBean_Finder : find Finds a bean
R::exec RedBean_Adapter_DBAdapter : exec Executes SQL
R::getAll RedBean_Adapter_DBAdapter : get Query the database
R::dup RedBean_DuplicationManager : setFilters, dup Duplicate a bean
R::exportAll RedBean_DuplicationManager : exportAll Export beans
R::associate RedBean_AssociationManager : associate Associate two beans
R::tag RedBean_TagManager : tag Tag a bean
R::related RedBean_AssociationManager : relatedSimple Retrieve related beans
R::commit RedBean_Adapter_DBAdapter : commit Commits transaction
R::begin RedBean_Adapter_DBAdapter : startTransaction Begins transaction
R::rollback RedBean_Adapter_DBAdapter : rollback Rolls back a transaction
R::nuke RedBean_QueryWriter : wipeAll Destroys database
R::dependencies RedBean_OODB : setDepList Sets dependent beans
R::getColumns RedBean_QueryWriter : getColumns List columns of a table
R::genSlots RedBean_SQLHelper : genSlots Generates slots
R::freeze RedBean_OODB : freeze Freezes the schema

Note that R::dup() first sets filters (if any) and then calls the dup() method on the Duplication Manager service object.

No Configuration

Most ORMs use configuration files (XML, INI or YAML) or some sort of annotation system to define mappings. These systems force you to map records to objects upfront. RedBeanPHP is different. Instead of using configuration it uses conventions; a very small set of rules. RedBeanPHP uses these conventions to infer relationships and to automate mappings. RedBeanPHP also helps you to follow these conventions by automatically building the initial tables and columns for you — which also saves a lot of time. This means there is no configuration, less boilerplate code and more time left to focus on the business logic, testing and documentation, thus boosting development productivity and code quality.

Dispense multiple beans

To dispense multiple beans at once:

RedBeanPHP 3.5 offers even more comfort for lazy developers:

Start your code with: R::useWriterCache(true); to make use of query caching. This will prevent RedBeanPHP from performing unnecessary queries. This feature is available since RedBeanPHP 3.4. While RedBeanPHP offers other caching mechanisms as well this is the easiest to use and it’s completely transparent!

Bean types may only consist of lowercase alphanumeric symbols a-z and 0-9 (no underscores). A property name has to begin with a letter and may consists of letters and numbers. Underscores in property names are allowed but I recommend to come up with better nouns instead. Underscores in Bean types are not allowed because RedBeanPHP uses these to identify relations. Underscores are used to denote a relation between two beans, therefore you should not dispense such beans yourself. The RedBeanPHP naming restrictions allow RedBeanPHP to figure out relationships among tables and beans without configuration; however these rules also help you to maintain a clean and consistent database schema. Moreover, developers often make up terrible names for tables (i.e. ‘tbl_userrights’, ‘person_Project’ etc…). I try to encourage people to take some time to find the correct ‘name’ (often a simple noun) for their beans (i.e. ‘privilege’,’participant’). This also improves the readability (and maintainability) of your database. Just take some time to find the noun that describes the entity you’re modelling best. If, for some reason you really need to break these rules use: Use R::setStrictTyping(false); This may cause some side effects with dup() and export() though.

As of RedBeanPHP 3.4, a property name like ‘singleMalt’ will be automatically converted to ‘single_malt’. If you don’t like that, use: RedBean_OODBBean::setFlagBeautifulColumnNames(false);

RedBeanPHP 5.4 (1 October 2019, St. Nicholas Edition)

  • Debug Logger now correctly handles typed bindings (author AbygailG)
  • R::store( $beans, ); (author Gabor, inspiration from PR David Sickmiller)
  • R::storeAll( $beans, );
  • R::findForUpdate() (author Gabor)
  • R::traverse(…,function( ,$depth){}) passes depth level (author Lynesth)
  • Allow findLike (and the likes) to use «IS NULL» conditions (author Lynesth)
  • Have trash/trashAll return number of deleted beans (author Lynesth)
  • Fixed Facade::removeToolBoxByKey removing the toolbox (thanks Dmelo)
  • R::getRow() now adheres to return type array (author Nucc1)
  • R::setAllowFluidTransactions() (thanks Lynesth and Marios88)
  • Peformance improvement of R::diff() (author Lynesth)
  • Fix Cache prevent a second FOR-UPDATE SQL query (author Gabor)
  • Additional unit tests
  • Improvement source code documentation

RedBeanPHP

  • Getting started
    • Welcome
    • Quick tour
    • System Requirements
    • Installing
    • Setup
    • Connect
  • Basics
    • Create a Bean
    • Loading a Bean
    • Deleting a Bean
    • Freeze
  • Finding
    • Finding Beans
    • Queries
    • Mixing SQL and PHP
  • Relation Mapping
    • One-to-many
    • Many-to-many
    • Parent Object
    • Counting beans
    • Eager loading
    • Aliasing
    • Trees
    • Enums and more
    • Tags
    • Cheatsheet
  • Models
    • Adding Models
    • FUSE
    • Custom Methods
    • Dependency Injection
  • Database
    • Schema
    • Multiple databases
    • Transactions
    • Nuke
  • Advanced
    • Association API
    • Copy Beans
    • Import and Export
    • Debug and log
    • Meta Data
    • Labels
    • Cooker
    • Cache
    • Internals
  • Project
    • FAQ
    • Roadmap
    • Branches and Versions
    • Beta Testing
    • Changelog
    • Upgrade
    • Plugins
    • License
    • Credits
  • Tools
    • Replica
    • BeanCan Server
    • REST server
    • Namespacer
    • RedUNIT
    • Archive

Point version

A point version or point release happens when the last digit has been increased. Note that although you might assume a digit normally varies from 0-9, you might encounter minor and point releases like X.X.12 or X.30.X. Not sure if this will happen, however as RedBeanPHP matures you will see less major upgrades and more minor upgrades and point releases. A point release version is normally a maintenance version. This may include bugfixes, new tests, documentation changes or just some code cleanup. While it’s always a good idea to scan the changelog most of the time you can be pretty sure there are no compatibility issues nor interesting new feature. Of course if you have reported an issue the point release can be quite interesting because the bug might have been fixed. In this case, the Github bug report number and the fix will be mentioned in the changelog.

back to main menu

RedBeanPHP

  • Getting started
    • Welcome
    • Quick tour
    • System Requirements
    • Installing
    • Setup
    • Connect
  • Basics
    • Create a Bean
    • Loading a Bean
    • Deleting a Bean
    • Freeze
  • Finding
    • Finding Beans
    • Queries
    • Mixing SQL and PHP
  • Relation Mapping
    • One-to-many
    • Many-to-many
    • Parent Object
    • Counting beans
    • Eager loading
    • Aliasing
    • Trees
    • Enums and more
    • Tags
    • Cheatsheet
  • Models
    • Adding Models
    • FUSE
    • Custom Methods
    • Dependency Injection
  • Database
    • Schema
    • Multiple databases
    • Transactions
    • Nuke
  • Advanced
    • Association API
    • Copy Beans
    • Import and Export
    • Debug and log
    • Meta Data
    • Labels
    • Cooker
    • Cache
    • Internals
  • Project
    • FAQ
    • Roadmap
    • Branches and Versions
    • Beta Testing
    • Changelog
    • Upgrade
    • Plugins
    • License
    • Credits
  • Tools
    • Replica
    • BeanCan Server
    • REST server
    • Namespacer
    • RedUNIT
    • Archive

Creating a service object

Many methods in the R-facade are just wrappers around calls to methods on one of these core objects: OODB, Writer and Adapter. However many static methods in R also call so-called service objects. Service objects offer secondary functionality. To instantiate a service object you need to pass the toolbox to its constructor. The toolbox contains the tools a service object needs to operate: the adapter to connect to the database, the OODB object to call basic ORM methods and the writer to write queries for the database.

Let’s consider an example. Let’s say we want to use a function like R::find() to find a bean, but we want to use objects rather than static methods. How do we accomplish this ? First, we glance at the table to discover we need to have an instance of the Finder to use this method. Finder is a service object, specialized in well,… finding stuff!

That’s it. Now we have an instance of the Finder service object. Now to find a bean use:

Now $x contains all compositions by Bach. Like the result of R::find(), $x contains a collection of beans. Unlike R::find() we had to build the service object ourselves.

Upgrade 3.3 to 3.4

Welcome to the RedBeanPHP ORM upgrade guide for upgrading from version 3.3 to version 3.4. RedBeanPHP 3.4 is a minor release, this means that it’s almost backward compatible with previous releases in the 3-series. However even in a minor release there might be minor incompatibilities because the product has to move forward. This chapter describes the minor backward compatibilities and how to deal with them.

No more escaping

RedBeanPHP 3.4 no longer has an $adapter->escape() / $database->Escape() method. RedBeanPHP has always offered parameter binding and parameter binding has always been the preferred way to write queries. The escape methods therefore have been confusing and might lead to SQL injection because people don’t know how to use them. Parameter binding is much more safe and this is why I have decided to remove the escape() methods completely. If you have code that relies on the escape() methods please rewrite this code to use parameter binding, it makes your code safer and more consistent. If you insist on using escaping instead of parameter binding you can still use the underlying PDO instance for this: R::$adapter->getDatabase->getPDO()->quote();.

TimeLine and Sync

RedBeanPHP has grown a little fat. Therefore I removed two plugins from the main distribution; namely TimeLine and Sync. Since they are only useful to some people I figured they can just as well remain on github. You can compile them into rb.php yourself using Replica the RedBeanPHP build tool.

Extra Cooker flag

The Cooker (R::graph()) — a tool in RedBeanPHP to quickly turn entire array hierarchies in bean hierarchies and store them in the database will now throw an exception if you want to load a bean (by providing an id). You can turn this off using: RedBean_Plugin_Cooker::enableBeanLoading(true);

Uppercase characters

Formally RedBeanPHP never allowed the use of uppercase chars in properties. However this was always easy to circumvent if you knew how. In RedBeanPHP 3.4 uppercase characters will be used to generate ‘beautiful’ column names. For instance, a property called ‘singleMalt’ will result in a column single_malt. The reason why RedBeanPHP never allowed uppercase chars (and still does not allow) is because this tends to cause inter-operating system issues as well as fundamental cross database issues (some OSes and database engines are case sensitive while others are not). However like I said the restriction was easy to circumvent if you studied the API carefully. In RedBeanPHP 3.4 You’ll have to turn off the beautifier to use circumvent the restriction using: RedBean_OODBBean::setFlagBeautifulColumnNames(false); Of course, I still recommend not to do this. Instead I hope you enjoy the beautiful underscore-columns, generated by the ‘beautifier’.

No more SET(1) in MySQL

From now on RedBeanPHP will use BOOLEAN (TINYINT 1) as the default column for boolean values instead of SET(1). This has been done to make the behaviour across database platforms more consistent. Also SET(1) columns have some issues regarding NULL because they either represent 1 or NULL (or empty) while TINYINT(1) can respresent NULL, TRUE (1) and FALSE (0). Unfortunately none of the database platforms has a good boolean column type (actually Postgres has a real boolean value but it’s too strict and required a cast for every comparison). Therefore I feel TINYINT or INTEGERS are the best way to represent booleans given the current state of database platforms.

RedBeanPHP 4 Additional Plugin Pack

As of RedBeanPHP 4, the core package has been trimmed down. Some less essential components have been moved to this plugin package during the clean-up. The plugin package contains the following components:

  • Support for CUBRID database for RedBeanPHP 4
  • BeanCan Server Version 1 and 2 for RedBeanPHP 4
  • Preloader (for eager loading features) for RedBeanPHP 4
  • SQLHelper, a Query Builder for RedBeanPHP 4
  • Old Cooker component for RedBeanPHP 4

Download the additional plugin pack for RedBeanPHP4.

Note that some of these plugins are considered deprecated. The Cooker and the Preloader have been replaced in RedBeanPHP 4 by different mechanisms. The SQLHelper is also considered deprecated. The CUBRID QueryWriter and the BeanCan Servers are still fully supported.

Upgrade 3.2 to 3.3

Welcome to the RedBeanPHP ORM upgrade guide for upgrading from version 3.2 to version 3.3. This guide describes possible issues when upgrading from release 3.2 to version 3.3. RedBeanPHP 3.3 is a minor release and offers new functionality. For the most part this release is backward compatible. You should be able to migrate your projects with ease. However there are some minor incompatible changes. These are discussed on this page.

Strict Bean Types

From 3.3 on bean types may only contain alphanumeric characters. The underscore is no longer allowed. The reason for this is that in RedBeanPHP the underscores signifies a relationship between two types; for instance ‘product_shop’ is recognized as a relational bean or link table representing the relation between a product and a shop. The strict typing feature can be overridden easily by issueing:

Keyless export

From 3.3 on, the bean export behaviour has become more consistent. Prior to 3.3 when you performed an export on a bean the lists would be returned as arrays indexed by the IDs. This is very problematic for Javascript to work with because it creates NULL entries for intermediate entries which is bad for performance and just ugly. On the other hand exportAll() never did this. In RedBeanPHP 3.3 this has changed. All exports now return keyless lists. If you need to old bahviour use:

With the new keyless exports I hope to increase the consistency throughout the library and improve support for more Javascript oriented development strategies.

Plugins

In RedBeanPHP 3.3 plugin functions no longer have hard coded facade methods. For instance the Cooker plugin provides a method R::graph(). This method still exists, but only in R. Not in the facade RedBean_Facade. These plugin extensions of R are now compiled into the R-class by the Replica Build Script. If you use these methods on the facade class itself you should replace this code using a find replace action on your project.


С этим читают