The Zend Engine 1.0 had no exception handling. The Zend Engine 2.0
introduces a exception model similar to that of other programming
- languages.
+ languages. But there is no catch all and no finally clause.
+
+ Old code that has no user-defined classes or functions 'catch',
+ 'throw' and 'try' will run without modifications.
+
+ Exceptions can be rethrown in catch blocks. Also it is possible to
+ have multiple catch blocks. In that case the caught exception is
+ compare with the classtype of each catch block from top to bottom
+ and the first block that has a 'instanceof' match gets executed.
+ When the catch block finishes execution continues at the end of
+ the last catch block. If no catch block has a 'instanceof' match
+ then the next try/catch block is searched until no more try/catch
+ blocks are available. In that case the exception is an uncaught
+ exception and the program terminates with showing the exception.
Example:
try {
throw new MyExceptionFoo('Hello');
}
-
catch (MyException $exception) {
$exception->Display();
}
+ catch (Exception $exception) {
+ echo $exception;
+ }
?>
+
+ Even though the above example shows that it is possible to define
+ exception classes that don't inherit from Exception it is best to
+ do so. This is because the internal Exception class can gather a
+ lot of information otherwise not available. The PHP code emulation
+ code would look something like shown below. The comments show the
+ meaning of each proerty and hence there getter methods. As the code
+ shows it is possible to read any available information by using the
+ getter methods. But since some og the methods are used internally
+ they are marked final. All in all the class is very restrictive
+ because it must be ensured that anything used internally always
+ works as expected.
+
+ Emulating class Exception:
- Old code that has no user-defined classes or functions 'catch',
- 'throw' and 'try' will run without modifications.
+ <?php
+ class Exception {
+ function __construct(string $message=NULL, int code=0) {
+ if (func_num_args()) {
+ $this->message = $message;
+ }
+ $this->code = $code;
+ $this->file = __FILE__; // of throw clause
+ $this->line = __LINE__; // of throw clause
+ $this->trace = debug_backtrace();
+ $this->string = StringFormat($this);
+ }
+
+ protected $message = 'Unknown exception'; // exception message
+ protected $code = 0; // user defined exception code
+ protected $file; // source filename of exception
+ protected $line; // source line of exception
+
+ private $trace; // backtrace of exception
+ private $string; // internal only!!
+
+ final function getMessage() {
+ return $this->message;
+ }
+ final function getCode() {
+ return $this->code;
+ }
+ final function getFile() {
+ return $this->file;
+ }
+ final function getTrace() {
+ return $this->trace;
+ }
+ final function getTraceAsString() {
+ return self::TraceFormat($this);
+ }
+ function _toString() {
+ return $this->string;
+ }
+ static private function StringFormat(Exception $exception) {
+ // ... a function not available in PHP scripts
+ // that returns all relevant information as a string
+ }
+ static private function TraceFormat(Exception $exception) {
+ // ... a function not available in PHP scripts
+ // that returns the backtrace as a string
+ }
+ }
+ ?>
+
+ If you derive your exception classes from this Exception base class
+ your exceptions will be nicely shown in the builtin handler for
+ uncaught exceptions.
* Dereferencing objects returned from functions.
$obj = Foo;
$str = (string) $obj; // call __toString()
+
+ echo $obj; // call __toString()
?>
* Reflection API