A large project I’ve been working on as of late has many moving parts. It allowed a lot of dynamic edits that utilized AJAX for sending dynamic information to and from a database. When errors occurred it was alright for me, because I could debug them however what it came the client… Well let’s just say they were convinced that with these errors their computer was going to spontaneous combust.
I’ll admit it now that I was a little lazy when developing some of the classes. I went back and modified them so that they would implement exception handling, only I went one step further and used custom exception handling so that I could log any errors that may occur.
Within this posting, im going to create a class that will have errors, and I’ll also create a custom exception class that will catch any of these errors and log them to a file

You can download the complete source here. This class will be a very basic SQL class that will:
- Connect to a database
- Disconnect from a database
- Select from a database
The directory setup after this tutorial should look as follows:
- index.php
- /lib/
- SQL.class.php
- SQL.exception.class.php
- /sql/
- world.sql
- SQLException.log
Directory Setup
Make sure you have the world database installed within your database. You can download it here or find it in the download of the completed source.
The SQL class
Before I jump into the mix, this is written for people whom already have a basic grasp on any OOP language, as well as some of the basics of exception handling.
SQL.class.php
<?php
include('SQL.exception.class.php');
class SQL {
private $username;
private $password;
private $database;
private $connection;
/**
*
*
*/
public function __construct($u,$p,$d) {
$this->username = $u;
$this->password = $p;
$this->database = $d;
$this->connection = false;
}
public function connect() {
if(!$this->connection) {
// use @ to surpress the error
if(!@mysql_connect('localhost',$this->username,$this->password)) {
throw new SQLException('Can\'t connect to the database, either the username or password are wrong');
}
// use @ to surpress the error
if (!@mysql_select_db($this->database)) {
throw new SQLException('The database '.$this->database.' does not exist.');
}
$this->connection = true;
}
}
public function disconnect() {
if($this->connection) {
mysql_close();
$this->connection = false;
}
}
public function getCity($city) {
$cities = array();
$query = 'SELECT * FROM City WHERE NAME ='."'$city'";
$results = @mysql_query($query);
if ($results) {
while($row = mysql_fetch_array($results)) {
$cities[] = $row;
}
if (sizeof($cities) > 0) {
return $cities;
}
else {
throw new SQLException('The following city: '.$city.' was not found',$query);
}
}
else {
throw new SQLException('Error with query when trying to get a city: ',$query);
}
}
}
?>
Theres the SQL class. Theres a few things in here that I should make note of. First, I’ve included the SQLException custom class, we have yet to create that, so hang on for now! Secondly the way that a try catch block works, is that it needs to try to do something and if that something does not work, it will catch that exception to better handle it. In order to catch an exception one must be thrown. We’re throwing the exceptions anytime we feel an error might need to be reported.
Next up the custom exception class
Create a new file within your lib folder called “SQL.exception.class.php”
SQL.exception.class.php
<?php
class SQLException extends Exception {
// path to the log file
private $log_file;
public function __construct($message=NULL, $query = NULL) {
// NOTE:: THIS MAY NEED TO CHANGE
$this->log_file = $_SERVER['DOCUMENT_ROOT'].'/'.$_SERVER['REQUEST_URI'].'/SQLException.log';
$code = mysql_errno();
$sql_error = mysql_error();
// open the log file for appending
if ($fp = fopen($this->log_file,'a')) {
// construct the log message
$log_msg = date("[Y-m-d H:i:s]") .
" Code: $code " .
" || Message: $message".
" || SQL error: $sql_error \n".
"Query: $query\n-------\n";
fwrite($fp, $log_msg);
fclose($fp);
}
// call parent constructor
parent::__construct($message, $code);
}
}
?>
All the magic here happens when we extend PHP’s Exception class. Moving down to the class constructor, I’ve set up two parameters. $message takes the message that will be passed into the parent constructor. This message will be shown to the user to better explain whats going. The second parameter $query is meant for the log file. This is passed in so that we as the developers can view the query that may have been botched. Moving into the constructor now, it’s important to provide a path to the logfile, so the first line of code we see does just that. Next the two variables $code and $sql_error grab a little more information for the log file. The las bit of code opens the log file, appends a new entry, saves and closes it. To finish the class off, run the parents constructor.
Finally the index or testing file.
This is the index file that will be within our root directory. It contains sets of variables to help generate exceptions. This file is also where we “try” to complete a statement and if anything goes wrong we “catch” that exception, kill the script and explain why things didn’t work out.
index.php
<?php
include_once('lib/SQL.class.php');
// ==================== EXCEPTION ERROR ====================
// switch these two database variables to see a exception error occur
$database = 'world';
//$database = 'wrongDB'; // <--- this will result in an exception error when uncommented.
// ==================== EXCEPTION ERROR ====================
// switch these two username variables to see a exception error occur
$username = 'root';
//$username = 'wrongUserName'; // <--- this will result in an exception error when uncommented.
// ==================== EXCEPTION ERROR ====================
// switch these two username variables to see a exception error occur
$password = 'root';
//$password = 'wrongPassword'; // <--- this will result in an exception error when uncommented.
// ==================== EXCEPTION ERROR ====================
// switch these two city variables to see a exception error occur
$city = 'Vancouver';
//$city = 'Gotham City'; // <--- this will result in an exception error when uncommented.
$db = new SQL($username,$password,$database);
/**
* try catch block.
* try - to connect to the database and once connected, disconnect.
* catch - any exception that will occur and kill the script.
*/
try {
$db->connect();
$db->disconnect();
} catch (SQLException $e) {
$db->disconnect();
die($e->getMessage());
}
/**
* try catch block
* try to connect to the database
* try to run a select query (note: to get an exception error change the city variable above)
* print the query
* disconnect
* catch any error that may occur.
*/
try {
$db->connect();
$r = $db->getCity($city);
// print the results
echo '<pre>';
print_r($r);
echo '</pre>';
$db->disconnect();
} catch (SQLException $e) {
$db->disconnect();
die($e->getMessage());
}
?>
Conclusion
Exception handling is a fun subject. The possibilities of being able to recover from errors that might occur create endless possibilities when scripting, just don’t do what I do and leave it all to the bitter end!
Write a Comment