Since my intention here is to demonstrate how to utilize only one subclass to handle all of the exceptions triggered when working with MySQL, first I'd like to list the complete source code corresponding to the practical example developed in the preceding tutorial of the series. As you'll surely recall, that example used two different subclasses to handle all of these MySQL-related exceptions. Having said that, here's how the example in question looked originally: // define 'MySQL' class class MySQL{ private $conId; private $host; private $user; private $password; private $database; private $result; const OPTIONS=4; public function __construct($options=array()){ if(count($options)!=self::OPTIONS){ throw new MySQLException('Invalid number of connection parameters'); } foreach($options as $parameter=>$value){ if(!$value){ throw new MySQLException('Invalid parameter '.$parameter); } $this->{$parameter}=$value; } $this->connectDB(); } // connect to MySQL private function connectDB(){ if(!$this->conId=mysql_connect($this->host,$this->user,$this->password)){ throw new MySQLException('Error connecting to the server'); } if(!mysql_select_db($this->database,$this->conId)){ throw new MySQLException('Error selecting database'); } } // run query public function query($query){ if(!$this->result=mysql_query($query,$this->conId)){ throw new MySQLException('Error performing query '.$query); } return new Result($this,$this->result); } } // define 'Result' class class Result{ private $mysql; private $result; public function __construct($mysql,$result){ $this->mysql=$mysql; $this->result=$result; } // fetch row public function fetchRow(){ if(!$row=mysql_fetch_assoc($this->result)){ return false; } return $row; } // count rows public function countRows(){ if(!$rows=mysql_num_rows($this->result)){ throw new ResultException('Error counting rows'); } return $rows; } // count affected rows public function countAffectedRows(){ if(!$rows=mysql_affected_rows($this->mysql->conId)){ throw new ResultException('Error counting affected rows'); } return $rows; } // get ID of last-inserted row public function getInsertID(){ if(!$id=mysql_insert_id($this->mysql->conId)){ throw new ResultException('Error getting ID'); } return $id; } // seek row public function seekRow($row=0){ if(!is_int($row)||$row<0){ throw new ResultException('Invalid result set offset'); } if(!mysql_data_seek($this->result,$row)){ throw new ResultException('Error seeking data'); } } } // extend the built-in exception class to throw MySQL-related exceptions class MySQLException extends Exception{ public function __construct($message,$code=0){ // call parent of Exception class parent::__construct($message,$code); } public function showExceptionInfo(){ return 'Catching MySQL exceptions...<br />Exception message: '.$this->getMessage().'<br />Source filename of exception: '.$this->getFile().'<br />Source line of exception: '.$this->getLine(); } } // extend the built-in exception class to throw MySQL data sets-related exceptions class ResultException extends Exception{ public function __construct($message,$code=0){ // call parent of Exception class parent::__construct($message,$code); } public function showResultExceptionInfo(){ return 'Catching Result exceptions...<br />Exception message: '.$this->getMessage().'<br />Source filename of exception: '.$this->getFile().'<br />Source line of exception: '.$this->getLine(); } } try{ // connect to MySQL $db=new MySQL(array('host'=>'host','user'=>'user,'password'=>'password','database'=>'database')); // fetch data on some users $result=$db->query('SELECT * FROM users'); // display data on some users while($row=$result->fetchRow()){ echo 'First Name: '.$row['firstname'].' Last Name: '.$row['lastname'].' Email: '.$row['email'].'<br />'; } // throw a Result Exception echo $result->getInsertID();
/* displays the following Catching Result exceptions... Exception message: Error getting ID Source filename of exception: path/to/file/exception_test.php Source line of exception: 93 */ } // catch MySQL exceptions here catch(MySQLException $e){ echo $e->showMySQLExceptionInfo(); exit(); } // catch Result exceptions here catch(ResultException $e){ echo $e->showResultExceptionInfo(); exit(); } // catch default exceptions here catch(Exception $e){ echo 'Catching default exceptions...<br />'; echo 'Exception message: '.$e->getMessage().'<br />'; echo 'Source filename of exception: '.$e->getFile().'<br />'; echo 'Source line of exception: '.$e->getLine(); exit(); } As you can see from the above example, I first defined a couple of MySQL handling classes for connecting to the server and selecting specific databases, running several SQL queries and processing results sets. However, apart from understanding how these classes do their respective things, undoubtedly the most important point to stress here is the way that the different MySQL-related exceptions are handled at runtime. In this case, I utilized two specific subclasses, called "MySQLException" and "ResultException" respectively. These subclasses separately handle the errors that might be triggered when connecting to the server and running SQL statements, and the failures that might happen when processing result sets. Pretty easy to understand, right? Now that you hopefully recalled how to use the two distinct subclasses to process all of the exceptions triggered by a couple of MySQL handling classes, it's time to see how to perform this same task by means of only one exception class. Keeping this idea in mind, in the next section I'm going show you how to merge the two exception subclasses that you saw before into a single one, which will implement the logic necessary to handle all of the MySQL-related exceptions in a more efficient manner. To see how this will be done, please click on the link that appears below and keep reading.
blog comments powered by Disqus |
|
|
|
|
|
|
|