PHP O/R mappers

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View

I was going to ask if there are any O/R (object-relation) mappers for
PHP.  I didn't find much on Google until I stumbled across .

My new question is: Are there any *great* O/R mappers for PHP?

My dream O/R mapper would have great performance, be intuitive to use,
allow me to switch out the DBMS, and remain well supported forever.  ;)


Re: PHP O/R mappers

There are no "standard" O/R mappers for the simple reason that only YOU know
the structure of YOUR objects and YOUR relational database, therefore only
YOU know how to map the two structures.

Personally I think that O/R mappers are an extra level of complexity that
can be made totally redundant, therefore they a complete waste of time. By
keeping the structure of my objects exactly the same as the structure of my
relational database I do not need to perform any mapping between the two

See for
another explanation.

Tony Marston

Quoted text here. Click to load it

Re: PHP O/R mappers


on 04/03/2005 01:44 AM David said the following:
Quoted text here. Click to load it

In that case you may want to look at Metastorage.


Manuel Lemos

PHP Classes - Free ready to use OOP components written in PHP /

PHP Reviews - Reviews of PHP books and other products /

Metastorage - Data object relational mapping layer generator

Re: PHP O/R mappers

David wrote:
Quoted text here. Click to load it

In this case, you don't need a mapper.  All you need to do
is to run a "SELECT * FROM" query on whatever database you
are using and then *_fetch_object() from the result.  This
is supported on MySQL (mysql_fetch_object()), PostgreSQL
(pg_fetch_object()), Microsoft SQL Server (mssql_fetch_object()),
and Oracle (oci_fetch_object()), to name a few.  


Re: PHP O/R mappers

NC wrote:

Quoted text here. Click to load it

No - that always returns a pseudo object with no methods which is really an
associative array with slightly different syntax. I think the OP is looking
for a way of defining/storing his own classes and storing/querying objects.

....which is possible using [un]serialize() and __autoload() but requires an
abstraction layer on top of the SQL interface.

Quoted text here. Click to load it



Re: PHP O/R mappers

Thanks.  A number of you to understand my question, but I'm
disappointed that there were no earthshattering solutions I had been

Tony: I understand your reasoning behind keeping the structure of your
objects the same as your database.  However, I would like a tool for
PHP that will automatically generate the objects based on the database
schema.  As long as I have a normalized database with nothing too
tricky, an automated tool should be able to do this.  (I am using
LLBLGen to do this for me on .NET.)  I addition to simply being lazy,
my theory is that the tool is less likely to introduce bugs than I am.

NC: I was not previously aware mysql_fetch_object(), and it looks like
it will do part of what I am looking for: it will return the database
entity stored as an object.  However, I want more.  I want to be able
to modify one of the objects attributes and then simply execute
something like or maybe to have it
automatically updated in the database.

Manuel: I saw your tool listed on the PHP wiki.  Do you know how
widespread its use is?

Colin: Yeah, basically I want to work with objects in my code but still
store everything in a normal RDBMS.  I know there are ways to natively
store objects in a database, but I don't trust those as much as
standard relational databases.  I'm glad to have entertained you with
the performance dream.

After doing some more research, it looks like MyObjects is one of the
bigger names in the niche market of PHP O/R mappers.  I am also
intrigued by some of the Ruby on Rails stuff but don't really
understand it yet.  (Of course, that would be a complete departure from


Re: PHP O/R mappers

David wrote:
Quoted text here. Click to load it

If I am not mistaken, most of O/R mappers out there are
code generators, not runtime mappers.  Which are you
interested in?

Quoted text here. Click to load it

OK, here's a rough MySQL-only draft or a run-time mapper:

class Mapper {
  var $host;
  var $user;
  var $password;
  var $db;
  var $table;
  var $link;
  var $data;
  var $primaryKey;
  var $error;

  function Mapper($host, $user, $password, $db, $table) {
    $this->link = mysql_connect($host, $user, $password);
    if ($this->link == false) {
      $this->error = mysql_error();
      return false;
    $db_selected = mysql_select_db($db, $this->link);
    if (!$db_selected) {
      $this->error = mysql_error();
    $this->host = $host;
    $this->user = $user;
    $this->password = $password;
    $this->db = $db;
    $this->table = $table;
    $this->error = false;

  function setPrimaryKey($key = '') {
    if ($key == '') {
      // Run "SHOW CREATE TABLE " and set
      // $this->primaryKey equal to the name of the
      // primary key field or, absent that, any key
      // field
    } else {
      $this->primaryKey = $key;

  function populate($key) {
    $query = "SELECT * FROM " .
             "WHERE = '$key'";
    $result = mysql_query($query);
    if ($result == false) {
      $this->error = mysql_error();
      return false;
    } else {
      $this->data = mysql_fetch_assoc($result);
      return true;

  function save() {
    $query = "UPDATE SET ";
    $add_comma = false;
    $where = '';
    foreach ($this->data as $field=>$value) {
      if ($add_comma) {
        $query .= ", $field='$value'";
      } else {
        $query .= "$field='$value'";
        $add_comma = true;
      if (strtolower($field) == strtolower($this->primaryKey)) {
        $where = " WHERE $field = $value";
    if ($where == '') {
      $this->error = 'No primary key found; ' .
                     'UPDATE will not be attempted.';
      return false;
    } else {
      $query .= $where;
      $result = mysql_query($query);
      if ($result) {
        return mysql_affected_rows();
      } else {
        $this->error = mysql_error();
        return false;


Example of usage:

$myMapper = new Mapper('localhost', 'root', 'password',
                       'myDB', 'myTable');
if ($myMapper->error) {
  die('Mapper Error: ' $myMapper->error);
$myMapper->data['description']    "New description for item ";


Re: PHP O/R mappers

NC wrote:

Quoted text here. Click to load it

PhpPeanuts supports polymorphism and navigational queries. It's SQL
generation objects can be selected by the user from a SearchPage. The
results are presented in pages with a limited length. The objects
already can be combined with AND and OR, next version will allow the
user to combine search objects in the search page too.

PhpPeanuts is fast because it has object caching, metadata caching, does
no implicit object copying and because it does not convert data from
MySQL when loading. It rather converts the data to the local format
(localization) when it is represented in the user interface.

PhpPeanuts supports navigation over 1 to n and n to 1 relationship roles
and reflects this in its user interface. You only have to define the
properties, no getters and setters are needed (but will be used if
defined). Next version will support n to m relationships in the user
interface by hiding intermediate relationship table objects. But earth
Quoted text here. Click to load it

phpPeanuts does runtime mapping.
Quoted text here. Click to load it

You can also just have a form that uses PntObjectSaveAction to convert
and validate the form, set the values on the object, then it calls
save(), and/or on errors, does forward to a page to give the user the
necessary feedback. It works for arbitrary classes that extend
PntDbObject. The forms can be generated automatically by


Henk Verhoeven,
For more info see

Site Timeline