1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
|
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision: 297028 $ -->
<chapter xml:id="language.exceptions" xmlns="http://docbook.org/ns/docbook">
<title>Exceptions</title>
<para>
PHP 5 has an exception model similar to that of other programming languages.
An exception can be <literal>throw</literal>n, and caught
("<literal>catch</literal>ed") within PHP. Code may be surrounded in a
<literal>try</literal> block, to facilitate the catching of potential
exceptions. Each <literal>try</literal> must have at least one
corresponding <literal>catch</literal> block. Multiple
<literal>catch</literal> blocks can be used to catch different classes of
exeptions. Normal execution (when no exception is thrown within the
<literal>try</literal> block, or when a <literal>catch</literal> matching
the thrown exception's class is not present) will continue after that last catch
block defined in sequence. Exceptions can be <literal>throw</literal>n (or
re-thrown) within a <literal>catch</literal> block.
</para>
<para>
When an exception is thrown, code following the statement will not be
executed, and PHP will attempt to find the first matching
<literal>catch</literal> block. If an
exception is not caught, a PHP Fatal Error will be issued with an
"<literal>Uncaught Exception ...</literal>" message, unless a handler has
been defined with <function>set_exception_handler</function>.
</para>
<para>
The thrown object must be an instance of the <classname>Exception</classname>
class or a subclass of <classname>Exception</classname>. Trying to throw an
object that is not will result in a PHP Fatal Error.
</para>
<note>
<para>
Internal PHP functions mainly use
<link linkend="ini.error-reporting">Error reporting</link>, only modern
<link linkend="language.oop5">Object oriented</link>
extensions use exceptions. However, errors can be simply translated to
exceptions with <link linkend="class.errorexception">ErrorException</link>.
</para>
</note>
<tip>
<para>
The <link linkend="intro.spl">Standard PHP Library (SPL)</link> provides a
good number of built-in exceptions.
</para>
</tip>
<example>
<title>Throwing an Exception</title>
<programlisting role="php">
<![CDATA[
<?php
function inverse($x) {
if (!$x) {
throw new Exception('Division by zero.');
}
else return 1/$x;
}
try {
echo inverse(5) . "\n";
echo inverse(0) . "\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
// Continue execution
echo 'Hello World';
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
0.2
Caught exception: Division by zero.
Hello World
]]>
</screen>
</example>
<example>
<title>Nested Exception</title>
<programlisting role="php">
<![CDATA[
<?php
class MyException extends Exception { }
class Test {
public function testing() {
try {
try {
throw new MyException('foo!');
} catch (MyException $e) {
/* rethrow it */
throw $e;
}
} catch (Exception $e) {
var_dump($e->getMessage());
}
}
}
$foo = new Test;
$foo->testing();
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
string(4) "foo!"
]]>
</screen>
</example>
<sect1 xml:id="language.exceptions.extending">
<title>Extending Exceptions</title>
<para>
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.
</para>
<example>
<title>The Built in Exception class</title>
<programlisting role="php">
<![CDATA[
<?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
}
?>
]]>
</programlisting>
</example>
<para>
If a class extends the built-in Exception class and re-defines the <link
linkend="language.oop5.decon">constructor</link>, it is highly recommended
that it also call <link
linkend="language.oop5.paamayim-nekudotayim">parent::__construct()</link>
to ensure all available data has been properly assigned. The <link
linkend="language.oop5.magic">__toString()</link> method can be overridden
to provide a custom output when the object is presented as a string.
</para>
<note>
<para>
Exceptions cannot be cloned. Attempting to <link
linkend="language.oop5.cloning">clone</link> an Exception will result in a
<literal>E_FATAL</literal> error.
</para>
</note>
<example>
<title>Extending the Exception class</title>
<programlisting role="php">
<![CDATA[
<?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";
?>
]]>
</programlisting>
</example>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->
|