HomePHP Page 2 - Building Object-Oriented Database Interfaces in PHP: Working with Multiple Data Access Objects
Getting in touch with a DB Interface: A brief look at the "DBI Generator" class - PHP
In previous articles in this series, we examined the concept of database interfaces, and saw source code for a "DBIGenerator" class. Working with multiple DB interfaces permits the accomplishment of several operations on many tables at the same time. Alejandro Gervasio demonstrates the power of this concept, with examples.
As usual, developers want to take a look at the source code of the class, so they gain a more detailed knowledge of its functionality. Therefore, in order to make available the full class code for implementation in projects, here is its complete listing:
class DBIGenerator{ var $table; var $name; var $path; function DBIGenerator($table,$name='default_file.php', $path='DEFAULTPATH/'){ $this->table=$table; $this->name=$name; $this->path=$path; } function generate(){ // build class header $str='<?php class '.$this->name.'{'; if(!$result=mysql_query("SHOW COLUMNS FROM $this->table")){ die('Could not run query '.mysql_error()); } // build data member declaration if(mysql_num_rows($result)>0){ while($row=mysql_fetch_array($result,MYSQL_ASSOC)){ $str.='var $'.$row['Field'].'='';'; $methods.='function set'.$row['Field'].'($'.$row['Field'].'){$this->'.$row ['Field'].'=$'.$row['Field'].';}'; $methods.='function get'.$row['Field'].'(){return $this->'.$row ['Field'].';}'; // store field names in array $fields[]=$row['Field']; } } // build empty constructor $str.='function '.$this->name.'(){}'; // build modifiers and accesors $str.=$methods; unset($methods); // build load() method $str.='function load(){$r=mysql_query("SELECT * FROM '.$this->table.' WHERE id='$this->id'");'; $str.='return mysql_fetch_array($r,MYSQL_ASSOC);}'; // build submit() method $str.='function submit(){mysql_query("INSERT INTO '.$this->table.' SET '; foreach($fields as $field){ $str.=($field!='id')?$field.'='$this->'.$field.'',':''; } $str.='");$this->id=mysql_insert_id();'; $str=preg_replace("/,"/",""",$str).'}'; // build update() method $str.='function update(){mysql_query("UPDATE '.$this->table.' SET '; foreach($fields as $field){ $str.=($field!='id')?$field.'='$this->'.$field.'',':''; } $str=preg_replace("/,$/","",$str); $str.=' WHERE id='$this->id'");}'; // build delete() method $str.='function delete(){mysql_query("DELETE FROM '.$this->table.' WHERE id='$this->id'");}'; $str.='}?>'; // write class code to file $fp=fopen($this->path.$this->name.'.php','w') or die('Failed opening file'); fwrite($fp,$str); fclose($fp); // delete temporary variables unset($fp,$str,$row,$fields,$field); } function getObject(){ // check if class file exists if(file_exists($this->path.$this->name.'.php')){ require_once($this->path.$this->name.'.php'); // create object return new $this->name; } return false; } }
Since the logic of the above "DBIGenerator" class was covered in detail in the second part of this series, I won't stop long for an explanation. Instead, I'll merely show a quick implementation, before jumping directly into the practical examples. So first, let's include the necessary class files, like this:
Notice that, besides including the required file for the "DBIGenerator" class, we're including the "MySQLConnector" class, which is handy for supplying database connectivity within the application. The next step involves the connection to MySQL, and the instantiation of a new object from the "DBIGenerator" class. We do it in the following way:
// instantiate a new MySQLConnector object $db=&new MySQLConnector(array('host'=>'host','user'=>'user','password'=>'password', 'database'=>'database')); // instantiate a new DBIGenerator object $g=&new DBIGenerator('users','User','DBICLASSES/');
The only thing to note here is that we're passing to the "DBIGenerator" class the name of an existing database table (in this case "users"), the name of the DBI class to be generated ("User"), and finally, the path where this class will be allocated.
Next, it's time to create the class file, by invoking the "generate()" method:
// generate class file $g->generate();
Finally, we're able to get the database access object returned by the "getObject()" method, as we see below:
// get an $user object if(!$user=$g->getObject()){ die('Failed to create object'); }
In this particular situation, we're working with a specific $user object. However, in accordance with the set of database tables involved in an application, we might be dealing with objects such as $clients, $products, $messages and so forth, or whatever data that can be stored in a database. As you can see, being able to communicate with multiple tables, through the databases classes associated, implies a very powerful technique.
Evidently, the next thing to do is look at the class that was dynamically generated after calling the "generate()" method. Want to see more? Just keep reading.