search for in the  
<Type HintingReferences Explained>
Last updated: Thu, 19 May 2005

Chapter 20. Exceptions

Table of Contents
Extending Exceptions

PHP 5 has an exception model similar to that of other programming languages. An exception can be thrown, try and caught within PHP. A Try block must include at least one catch block. Multiple catch blocks can be used to catch different classtypes; execution will continue after that last catch block defined in sequence. Exceptions can be thrown within catch blocks.

When an exception is thrown, code following the statement will not be executed and PHP will attempt to find the first matching catch block. If an exception is not caught a PHP Fatal Error will be issued with an Uncaught Exception message, unless there has been a handler defined with set_exception_handler().

Example 20-1. Throwing an Exception

<?php
try {
  
$error = 'Always throw this error';
   throw new
Exception($error);

  
// Code following an exception is not executed.
  
echo 'Never executed';

} catch (
Exception $e) {
   echo
'Caught exception: '$e->getMessage(), "\n";
}

// Continue execution
echo 'Hello World';
?>

Extending Exceptions

A User defined Exception class can be defined by extending the built-in Exception class. The members and properties below, show what is accessible within the child class that derives from the built-in Exception class.

Example 20-2. The Built in Exception class

<?php
class Exception
{
   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

  
function __construct($message = null, $code = 0);

   final function
getMessage();                // message of exception
  
final function getCode();                  // code of exception
  
final function getFile();                  // source filename
  
final function getLine();                  // source line
  
final function getTrace();                  // an array of the backtrace()
  
final function getTraceAsString();          // formated string of trace

   /* Overrideable */
  
function __toString();                      // formated string for display
}
?>

If a class extends the built-in Exception class and re-defines the constructor, it is highly recomended that it also call parent::__construct() to ensure all available data has been properly assigned. The __toString() method can be overriden to provide a custom output when the object is presented as a string.

Example 20-3. Extending the Exception class

<?php
/**
 * Define a custom exception class
 */
class MyException extends Exception
{
  
// Redefine the exception so message isn't optional
  
public function __construct($message, $code = 0) {
      
// some code
  
       // make sure everything is assigned properly
      
parent::__construct($message, $code);
   }

  
// custom string representation of object */
  
public function __toString() {
       return
__CLASS__ . ": [{$this->code}]: {$this->message}\n";
   }

   public function
customFunction() {
       echo
"A Custom function for this type of exception\n";
   }
}


/**
 * Create a class to test the exception
 */
class TestException
{
   public
$var;

   const
THROW_NONE    = 0;
   const
THROW_CUSTOM  = 1;
   const
THROW_DEFAULT = 2;

   function
__construct($avalue = self::THROW_NONE) {

       switch (
$avalue) {
           case
self::THROW_CUSTOM:
              
// throw custom exception
              
throw new MyException('1 is an invalid parameter', 5);
               break;

           case
self::THROW_DEFAULT:
              
// throw default one.
              
throw new Exception('2 isnt allowed as a parameter', 6);
               break;

           default:
              
// No exception, object will be created.
              
$this->var = $avalue;
               break;
       }
   }
}


// Example 1
try {
  
$o = new TestException(TestException::THROW_CUSTOM);
} catch (
MyException $e) {      // Will be caught
  
echo "Caught my exception\n", $e;
  
$e->customFunction();
} catch (
Exception $e) {        // Skipped
  
echo "Caught Default Exception\n", $e;
}

// Continue execution
var_dump($o);
echo
"\n\n";


// Example 2
try {
  
$o = new TestException(TestException::THROW_DEFAULT);
} catch (
MyException $e) {      // Doesn't match this type
  
echo "Caught my exception\n", $e;
  
$e->customFunction();
} catch (
Exception $e) {        // Will be caught
  
echo "Caught Default Exception\n", $e;
}

// Continue execution
var_dump($o);
echo
"\n\n";


// Example 3
try {
  
$o = new TestException(TestException::THROW_CUSTOM);
} catch (
Exception $e) {        // Will be caught
  
echo "Default Exception caught\n", $e;
}

// Continue execution
var_dump($o);
echo
"\n\n";


// Example 4
try {
  
$o = new TestException();
} catch (
Exception $e) {        // Skipped, no exception
  
echo "Default Exception caught\n", $e;
}

// Continue execution
var_dump($o);
echo
"\n\n";
?>


User Contributed Notes
Exceptions
jd at wuputah dot com
06-May-2005 10:15
PHP5 supports exception throwing inside a function, and catching it outside that function call. There is no mention of this in documentation but it works just fine, as tested by this sample code:

<?php

function exceptionFunction() {
       throw new
Exception("Throwing an exception!");
}

try {
      
exceptionFunction();
} catch (
Exception $e) {
       echo
"Exception caught!\n";
}

?>

The result in PHP 5.0.3 is "Exception caught!"

Further tests show that nested functions with exceptions, methods throwing exceptions, etc all work the same way. This is like declaring all classes (or methods) in Java as "class ClassName throws Exception". While I consider this a good thing, you should be aware that any thrown exception will propagate up your stack until it is either caught or runs out of stack.
ravindra at gatewaytechnolabs dot com
29-Oct-2004 04:34
<?php
/*I add here example for nested Exception Handling.*/
 
try
 {
   try
   {
     throw new
exception();
   }
   catch(
exception $m)
   {
   print
$m;
   print
"<br>";
   print
"inner exception"."<br>";
   }
   throw new
exception();
 }
 catch(
exception $e)
 {
  print
$e;
  print
"outer exception";
 }
 
?>
gomikochar at yahoo dot com
10-Oct-2004 10:00
To re-throw an exception, you must specify the name of the variable after throw in the catch block, i.e.,

<?php

try {
  try {
   throw new
Exception("Unknown error");
  }
  catch (
Exception $ie) {  // Inner Catch Block
  
throw;  // this will NOT work; parse error
  
throw $ie// this will re-throw the exception to the outer catch block
 
}
}
catch (
Exception $oe) {  // Outer Catch Block
 
echo $oe;
}

?>
php5 at grapio dot nl
06-Oct-2004 09:16
The base exception class, which is build in PHP5 has also a function getLine(). This is as expected if you look at the class define. But it is not noticed there.
I had just this code:
<?php
try
{
     throw new
Exception("test")
}
catch (
Exception $e)
{
  echo
$e->getLine()
}
?>
And this worked.
ravindra at gatewaytechnolabs dot com
01-Oct-2004 07:23
Like Java php5 also supports nesting of try catch.
moirae at centrum dot cz
21-Aug-2004 09:16
Really good article about exceptions in php5: http://www.zend.com/php5/articles/php5-exceptions.php

<Type HintingReferences Explained>
 Last updated: Thu, 19 May 2005
Copyright © 2001-2005 The PHP Group
All rights reserved.
This unofficial mirror is operated at: The Server Pages
Last updated: Thu May 19 18:35:34 2005 EDT