Home arrow PHP arrow Page 2 - Building a Modular Exception Class in PHP 5

Review: Handling MySQL-related exceptions with two subclasses - PHP

Welcome to the final part of the four-part series “Subclassing exceptions in PHP 5.” By means of a hands-on approach, this series walks you through using inheritance to build finely-tuned exception subclasses. These subclasses can be used to handle, via multiple “try-catch” blocks, several failures that might occur during the execution of a given web application.

TABLE OF CONTENTS:
  1. Building a Modular Exception Class in PHP 5
  2. Review: Handling MySQL-related exceptions with two subclasses
  3. Centralizing the processing of MySQL-related exceptions
  4. Handling MySQL-related exceptions through one single subclass
By: Alejandro Gervasio
Rating: starstarstarstarstar / 2
November 05, 2008

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

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.



 
 
>>> More PHP Articles          >>> More By Alejandro Gervasio
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PHP ARTICLES

- Hackers Compromise PHP Sites to Launch Attac...
- Red Hat, Zend Form OpenShift PaaS Alliance
- PHP IDE News
- BCD, Zend Extend PHP Partnership
- PHP FAQ Highlight
- PHP Creator Didn't Set Out to Create a Langu...
- PHP Trends Revealed in Zend Study
- PHP: Best Methods for Running Scheduled Jobs
- PHP Array Functions: array_change_key_case
- PHP array_combine Function
- PHP array_chunk Function
- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: