DZone 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
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:
<?php
require_once 'DB.php';
$db = DB::connect("mysql://blah:blah@server/databaseName"); //Defined elsewhere
$db->setFetchMode( DB_FETCHMODE_ASSOC );
?>
Next, we have our core object.
<?php
class Core {
/**
* Process and extract values from an associative array.
*
* Improve performance and overload in child classes.
*
* @param mixed[] $array Typically an assoc array from a DB::result->fetchRow.
* @return bool
*/
public function updateFromArray($array) {
if ( is_array($array) ) {
$class = new ReflectionObject($this);
$properties = $class->getProperties();
for ($i = 0; $i < count($properties); $i++) {
$prop_name = $properties[$i]->getName();
if (array_key_exists($prop_name, $array)) {
$this->$prop_name = @$array[$prop_name];
}
}
}
return true;
}
}
?>
So, when we do a query we can mash up everything nicely (assuming we don't have two tables with the same column names):
$sql = "SELECT * FROM table t JOIN table2 t2 ON t.table_id = t2.table_id";
$result = $db->query($sql);
while ($row = $result->fetchRow()) {
$t = new Table();
$t2 = new Table2();
$t->updateFromArray($row);
$t2->updateFromArray($row);
//Do whatever you like with your objects...
}
... and our objects get efficiently populated with data in a single query. The behind the scenes magic...
class Table extends DO_Table {
//Business logic
}
class Table2 extends DO_Table2 {
//Business logic
}
class DO_Table extends DB_DataObject {
public $field;
}
class DO_Table extends DB_DataObject {
public $field2;
}
class DB_DataObject extends Core {
}
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.





