Before I show you how to implement a basic error handling mechanism that works in conjunction with the “__autoload()” PHP 5 magic function, first I’d like you to recall the respective signatures of the two examples that I built in the previous articles of the series. As you recall, the first one showed how a primitive database-driven application used a couple of “require_once()” PHP functions to load into client code all of its source classes, and the second case performed this same task, but this time using the “__autoload()” function. Having said that, I’m going to start listing the definitions of the two MySQL processing classes that I used with the examples, which resided on different files. The first of these classes was called “MySQL,” and was stored on a “mysql.php” file. It was defined in the following way: (definition of mysql.php file) <?php class MySQL{ private $host; private $user; private $password; private $database; private $connId; // constructor function __construct($options=array()){ if(!is_array($options)){ throw new Exception('Connection options must be an array'); } foreach($options as $option=>$value){ if(empty($option)){ throw new Exception('Connection parameter cannot be empty'); } $this->{$option}=$value; } $this->connectDb(); } // private 'connectDb()' method private function connectDb(){ if(!$this->connId=mysql_connect($this->host,$this->user,$this->password)){ throw new Exception('Error connecting to MySQL'); } if(!mysql_select_db($this->database,$this->connId)){ throw new Exception('Error selecting database'); } } // public 'query()' method public function query($sql){ if(!$result=mysql_query($sql)){ throw new Exception('Error running query '.$sql.' '.mysql_error()); } return new Result($this,$result); } } ?> Now that you have seen the definition of the PHP file that housed the previous “MySQL” class, please take a look at “result.php,” which contained another class, named “Result”: (definition of result.php file) <?php class Result{ private $mysql; private $result; // constructor public function __construct($mysql,$result){ $this->mysql=$mysql; $this->result=$result; } // public 'fetch()' method public function fetch(){ return mysql_fetch_array($this->result,MYSQL_ASSOC); } // public 'count()' method public function count(){ if(!$rows=mysql_num_rows($this->result)){ throw new Exception('Error counting rows'); } return $rows; } // public 'get_insertId()' method public function getInsertId(){ if(!$insId=mysql_insert_id($this->mysql->connId)){ throw new Exception('Error getting insert ID'); } return $insId; } // public 'seek()' method public function seek($row){ if(!int($row)&&$row<0){ throw new Exception('Invalid row parameter'); } if(!$row=mysql_data_seek($this->mysql->connId,$row)){ throw new Exception('Error seeking row'); } return $row; } // public 'getAffectedRows()' method public function getAffectedRows(){ if(!$rows=mysql_affected_rows($this->mysql->connId)){ throw new Exception('Error counting affected rows'); } return $rows; } } ?> So far, so good. At this point you hopefully recalled the respective signatures of the two source classes listed above, so take a close look at the following hands-on examples. The first one uses a pair of simple PHP includes to load these classes into client code, and the final one utilizes the “__autoload()” function instead to do this. Here are the corresponding code samples: (example using conventional PHP includes) try{ // include required classes require_once 'mysql.php'; require_once 'result.php'; // connect to MySQL $db=new MySQL(array // fetch users from database table $result=$db->query('SELECT * FROM users ORDER BY id'); // display user data while($row=$result->fetch()){ echo 'Id: '.$row['id'].' First Name: '.$row['firstname'].' Last Name: '.$row } } catch(Exception $e){ echo $e->getMessage(); exit(); } // example using the magic '__autoload()' function function __autoload($className){ require_once $className.'.php'; } try{ // connect to MySQL $db=new MySQL(array // fetch users from database table $result=$db->query('SELECT * FROM users ORDER BY id'); // display user data while($row=$result->fetch()){ echo 'Id: '.$row['id'].' First Name: '.$row['firstname'].' Last Name: '.$row } } catch(Exception $e){ echo $e->getMessage(); exit(); }
As you can see, the above examples look nearly the same, at least when analyzed superficially. However, you’ll notice that the last code sample uses the handy “__autoload()” function to include the respective “MySQL” and “Result” classes that you saw before. Of course, the major advantage in utilizing this function is that it allows you to easily load multiple classes behind the scenes, without having to explicitly declare several “require_once()” PHP functions. Quite convenient, right? Now that I provided you with two comparative examples of loading source classes onto a basic database-driven application using well-differentiated approaches (naturally, both are valid), it’s time to see how to improve the existing capacity of the “__autoload()” magic function. Our next step will be incorporating a simple error handling mechanism into it, which can be useful for triggering different errors when a given object-oriented application fails to include a certain source class into client code. To see how this error processing capability will be added to the “__autoload()” function, please click on the link that appears below and keep reading.
blog comments powered by Disqus |
|
|
|
|
|
|
|