CHAPTER 4 ■ ADVANCED FEATURES
throw new Exception("file '{$this->file}' is not writeable");
}
file_put_contents( $this->file, $this->xml->asXML() );
}
The __construct() and write() methods can now check diligently for file errors as they do their
work, but let code more fitted for the purpose decide how to respond to any errors detected.
So how does client code know how to handle an exception when thrown? When you invoke a
method that may throw an exception, you can wrap your call in a try clause. A try clause is made up of
the try keyword followed by braces. The try clause must be followed by at least one catch clause in
which you can handle any error, like this:
try {
$conf = new Conf( dirname(FILE)."/conf01.xml" );
print "user: ".$conf->get('user')."\n";
print "host: ".$conf->get('host')."\n";
$conf->set("pass", "newpass");
$conf->write();
} catch ( Exception $e ) {
die( $e->__toString() );
}
As you can see, the catch clause superficially resembles a method declaration. When an exception is
thrown, the catch clause in the invoking scope is called. The Exception object is automatically passed in
as the argument variable.
Just as execution is halted within the throwing method when an exception is thrown, so it is within
the try clause—control passes directly to the catch clause.
Subclassing Exception
You can create classes that extend the Exception class as you would with any user-defined class. There
are two reasons why you might want to do this. First, you can extend the class’s functionality. Second,
the fact that a derived class defines a new class type can aid error handling in itself.
You can, in fact, define as many catch clauses as you need for a try statement. The particular catch
clause invoked will depend upon the type of the thrown exception and the class type hint in the
argument list. Here are some simple classes that extend Exception:
class XmlException extends Exception {
private $error;
function construct( LibXmlError $error ) {
$shortfile = basename( $error->file );
$msg = "[{$shortfile}, line {$error->line}, col {$error->column}] ➥
{$error->message}";
$this->error = $error;
parent::construct( $msg, $error->code );
}
function getLibXmlError() {
return $this->error;
}
}
class FileException extends Exception { }