Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

About this user

Daniel O'Connor http://clockwerx.blogspot.com/

« Newer Snippets
Older Snippets »
Showing 1-1 of 1 total  RSS 

PEAR::DB, DataObjects, and Joins / Reflection

PEAR::DB_DataObject is great. I really like it. We don't use it at work, though; having gone for a slightly different route. This pattern should be applicable, however, quite nicely to DB_DataObject.

First, the database is set to associative fetching - our results come out as neat little arrays with fieldnames, so a $row = $db->query(/*blah*/)->fetchRow(); makes $row["id"], $row["field"], etc...


Configuration:
   1  
   2  <?php
   3  require_once 'DB.php';
   4  
   5  $db = DB::connect("mysql://blah:blah@server/databaseName"); //Defined elsewhere
   6  $db->setFetchMode( DB_FETCHMODE_ASSOC );
   7  
   8  
   9  ?>


Next, we have our core object.
   1  
   2  <?php
   3  class Core {
   4  
   5  
   6      /**
   7       * Process and extract values from an associative array.
   8       *
   9       * Improve performance and overload in child classes.
  10       *
  11       * @param   mixed[]    $array  Typically an assoc array from a DB::result->fetchRow.
  12       * @return  bool
  13       */
  14      public function updateFromArray($array) {
  15                  
  16          if ( is_array($array) ) {
  17  
  18              $class = new ReflectionObject($this);
  19              $properties = $class->getProperties();
  20  
  21              for ($i = 0; $i < count($properties); $i++) {
  22                  $prop_name = $properties[$i]->getName();
  23  
  24                  if (array_key_exists($prop_name, $array)) {
  25                      $this->$prop_name = @$array[$prop_name];
  26                  }
  27              }
  28          }
  29  
  30          return true;
  31      }
  32  }
  33  ?>


So, when we do a query we can mash up everything nicely (assuming we don't have two tables with the same column names):

   1  
   2  $sql = "SELECT * FROM table t JOIN table2 t2 ON t.table_id = t2.table_id";
   3  
   4  $result = $db->query($sql);
   5  
   6  while ($row = $result->fetchRow()) {
   7     $t = new Table();
   8     $t2 = new Table2();
   9  
  10     $t->updateFromArray($row);
  11     $t2->updateFromArray($row);
  12  
  13     //Do whatever you like with your objects...
  14  }


... and our objects get efficiently populated with data in a single query.

The behind the scenes magic...
   1  
   2  class Table extends DO_Table {
   3  //Business logic
   4  }
   5  
   6  class Table2 extends DO_Table2 {
   7  //Business logic
   8  }
   9  
  10  class DO_Table extends DB_DataObject {
  11       public $field;
  12  }
  13  
  14  
  15  class DO_Table extends DB_DataObject {
  16       public $field2;
  17  }
  18  
  19  class DB_DataObject extends Core {
  20       
  21  }


Now... there's a few gotchas with this; which is why we don't use DB_DataObject - you can accidentally overwrite information you shouldn't from Core::updateFromArray();

There's no validation - you have to trust the array data you pass to the object.

You have to watch your 'specialist' doesn't do anything silly like Table::updateFromArray($_REQUEST);

You are limited to one row, one *type* of object - you couldn't join a table to itself and such.
« Newer Snippets
Older Snippets »
Showing 1-1 of 1 total  RSS