PHP ORM Comparison

Written on May 24, 2015
Estimated reading time : 7 mins
Tags : | database | orm | php |

About

  • In my previous post, I had talked about some of the pros, cons of working with an ORM & when it can be useful.
  • In this post, I take a look at some prominent PHP based ORMs & compare them.

Features of a Good ORM

  • Community support
  • Comprehensive support for various relational databases (enables easier migration)
  • Auto Generation of Entity Classes
  • Support for Dirty-checking
  • Support for a powerful query language (SQL / HQL / DQL etc)
  • Cascading actions
  • Support for event triggering
  • Good Documentation

Different PHP based ORMs

  • Doctrine (DataMapper pattern)
  • Propel (ActiveRecord pattern)
  • Redbean (DataMapper pattern)
  • Idiorm (ActiveRecord pattern but oriented towards Query Language)
  • Paris (ActiveRecord pattern & dependent on Idiorm)
  • Spot ORM (DataMapper pattern built on top of Doctrine DBAL)
  • Outlet (DataMapper pattern)
  • Xyster (DataMapper pattern)
  • Leap (Kohana FW)
  • Eloquent (Laravel FW)
  • MicroMVC
  • Gacela
  • NotORM

  • some more which have fallen into the cracks of the internet now due to lack of maintenance.

Comparison

  • We can ignore most of the entries in the list above since they suffer from atleast one of the following :
    • Lack of community support (GitHub contributors list is very low)
    • Authors have stopped maintenance
    • ORM is tightly coupled with a non enterprise level PHP Framework
    • ORM depends on another ORM DBAL for its functionality
  • I am keeping Idiorm & Paris out of the comparison too since they are quite lightweight compared to the others + they aren’t adding any more features now. Their notice on Github - “Please do not submit feature requests or pull requests adding new features as they will be closed without ceremony.”
  • So the comparison will be between Doctrine, Propel & Redbeans.

Initial release date

  • Doctrine
    • September 1, 2008
  • Propel
    • August 2003
  • Redbeans
    • 2009

Community Support

  • Doctrine
    • Github Stats : 389 contributors (as of 2015-05-09)
  • Propel
    • Github Stats : 96 contributors (as of 2015-05-09)
  • Redbeans
    • Github Stats : 31 contributors (as of 2015-05-09)

Configuration file format

  • Doctrine
    • PHP
    • YML
    • XML
  • Propel
    • XML
    • YML
    • PHP (only for schemas)
    • JSON (only for schemas)
    • INI (only for schemas)
  • Redbeans
    • NO CONFIG !

Generation of Classes from database tables

  • Doctrine
    • Entity classes are generated via command line
  • Propel
    • XML Schema generated via command line which leads to around 7 PHP model classes
  • Redbeans
    • Beans created automatically during code execution

Generation of database tables from Classes

  • Doctrine
    • Tables are generated via command line
  • Propel
    • Tables are generated via command line
  • Redbeans
    • Tables created automatically during code execution

Support for Dirty-checking

  • Doctrine
    • Yes
  • Propel
    • Yes
  • Redbeans
    • No

Support for query language for complex operations

  • Doctrine
    • Yes (SQL, DQL)
  • Propel
    • Yes (SQL in object form)
  • Redbeans
    • Yes (SQL)

Cascading actions

  • Doctrine
    • Yes
  • Propel
    • Yes
  • Redbeans
    • Yes

Support for event triggering

  • Doctrine
    • Yes
  • Propel
    • Yes
  • Redbeans
    • Yes

Good Documentation

  • Doctrine
    • Comprehensive
  • Propel
    • Yes
  • Redbeans
    • User friendly & concise

Comprehensive support for various relational databases

  • Doctrine
    • MySQL
    • Postgres
    • SQLite
    • Oracle
    • MSSQL
    • IBM DB2
    • Interfaces to extend support to other databases
  • Propel
    • MySQL
    • Postgres
    • SQLite
    • Oracle
    • MSSQL
  • Redbeans
    • MySQL
    • Postgres
    • SQLite

Code Examples

  • Doctrine

        
      $author = new Author();
      $author->setFirstName("Leo");
      $author->setLastName("Tolstoy");
      // no need to save the author yet
        
      $book = new Book();
      $book->setTitle("War & Peace");
      $book->setIsbn("0140444173");
      $book->setAuthor($author);
        
      $entityManager()->persist($book);
      $entityManager()->flush();
      // saves both objects!
    
    
  • Propel

        
      $author = new Author();
      $author->setFirstName("Leo");
      $author->setLastName("Tolstoy");
      // no need to save the author yet
    
      $book = new Book();
      $book->setTitle("War & Peace");
      $book->setIsbn("0140444173");
      $book->setAuthor($author);
      $book->save(); 
      // saves both objects
    
    
  • Redbeans

        
      R::setup();
      $movie = R::dispense('movie');
      $movie->title = 'Beans in space';
      $character = R::dispense('character');
      $character->name = 'hero';
      $movie->ownActorList[] = $character;
      $id = R::store($movie);
      // stores both objects
    
    

Pros

  • Doctrine
    • Since it is adapted from Hibernate, it supports various functionalities & scenarios
  • Propel
    • XML config which is easy to read
    • Recommendation of where to place business logic
    • IDE friendly
    • Easier migration
    • Core library supports a lot of features.
    • Fast
  • Redbeans
    • Ease of use with zero config

Cons

  • Doctrine
    • Documentation is limited to database activity & its upto the user to decide where to place business logic
    • Requires extensions for using out of the box functionality like soft delete
    • Requires opcode cache layer to be somewhat fast
    • Higher learning curve
  • Propel
    • Requires an extra build step
    • ActiveRecord pattern (sometimes called an anti pattern)
  • Redbeans
    • Limitations in abilities compared to Doctrine
    • For existing database, the schema has to be as per RedBeans conventions
    • Enterprise level usage cases are less

Recommendation

  • Your choice of an ORM should be based on which design pattern suits your application.
  • Doctrine follows Datamapper pattern while Propel follows an Active Record design pattern.
  • Both are well supported in enterprise level frameworks like Symfony
  • I would prefer using Redbeans on my personal side projects since its pretty neat to work with. But I would definitely hesitate to use it with a client’s project.




Feel free to share this article :

submit to reddit

Add your thoughts, questions, doubts, suggestions as comments below :