It's important to note some unexpected behavior when overriding the __toString method of an Exception. The default PHP exception handler will truncate the result of the __toString method to the number of bytes specified by log_errors_max_len in php.ini.
To get around this problem, you need to either change the value of log_errors_max_len:
<?php
// recommended: disable error logging
// so the log files don't become bloated from huge
// exception strings
ini_set('log_errors','off');
// log_errors_max_len = infinite length
ini_set("log_errors_max_len",0);
?>
or specify a custom exception handler:
<?php
function long_exception_handler($exception) {
// for compatibility, call __toString
echo $exception->__toString();
}
set_exception_handler('long_exception_handler');
?>
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.
Przykład #1 The Built in Exception class
<?php
class Exception
{
protected $message = 'Unknown exception'; // exception message
private $string; // __toString cache
protected $code = 0; // user defined exception code
protected $file; // source filename of exception
protected $line; // source line of exception
private $trace; // backtrace
private $previous; // previous exception if nested exception
public function __construct($message = null, $code = 0, Exception $previous = null);
final private function __clone(); // Inhibits cloning of exceptions.
final public function getMessage(); // message of exception
final public function getCode(); // code of exception
final public function getFile(); // source filename
final public function getLine(); // source line
final public function getTrace(); // an array of the backtrace()
final public function getPrevious(); // previous exception
final public function getTraceAsString(); // formatted string of trace
/* Overrideable */
public function __toString(); // formatted string for display
}
?>
If a class extends the built-in Exception class and re-defines the constructor, it is highly recommended that it also call parent::__construct() to ensure all available data has been properly assigned. The __toString() method can be overridden to provide a custom output when the object is presented as a string.
Informacja: Exceptions cannot be cloned. Attempting to clone an Exception will result in a E_FATAL error.
Przykład #2 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, Exception $previous = null) {
// some code
// make sure everything is assigned properly
parent::__construct($message, $code, $previous);
}
// 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 is not 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); // Null
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); // Null
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); // Null
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); // TestException
echo "\n\n";
?>
Extending Exceptions
18-Feb-2010 11:18
31-Dec-2009 11:17
As previously noted exception linking was recently added (and what a god-send it is, it certainly makes layer abstraction (and, by association, exception tracking) easier).
Since <5.3 was lacking this useful feature I took some initiative and creating a custom exception class that all of my exceptions inherit from:
<?php
class SystemException extends Exception
{
private $previous;
public function __construct($message, $code = 0, Exception $previous = null)
{
parent::__construct($message, $code);
if (!is_null($previous))
{
$this -> previous = $previous;
}
}
public function getPrevious()
{
return $this -> previous;
}
}
?>
Hope you find it useful.
24-Nov-2009 03:37
Support for exception linking was added in PHP 5.3.0. The getPrevious() method and the $previous argument to the constructor are not available on any built-in exceptions in older versions of PHP.
17-Jan-2009 09:32
I have written similar simple custom exception class. Helpful for newbie.
<?php
/*
This is written for overriding the exceptions.
custom exception class
*/
error_reporting(E_ALL-E_NOTICE);
class myCustomException extends Exception
{
public function __construct($message, $code=0)
{
parent::__construct($message,$code);
}
public function __toString()
{
return "<b style='color:red'>".$this->message."</b>";
}
}
class testException
{
public function __construct($x)
{
$this->x=$x;
}
function see()
{
if($this->x==9 )
{
throw new myCustomException("i didnt like it");
}
}
}
$obj = new testException(9);
try{
$obj->see();
}
catch(myCustomException $e)
{
echo $e;
}
?>
