mirror of
https://github.com/sigmasternchen/php-doc-en
synced 2025-03-17 01:18:55 +00:00

What's done: the migration guide itself, updates to existing functions and functionality, and new language features. What's not done: stub pages for new functions and methods. (I'd rather get this in now, though, than have it languish on my hard drive any longer so that other people can contribute.) What could use help: the generator chapter is pretty rough and ready. Better examples would be awesome. I certainly won't argue if somebody wants to add the function stubs, either. git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@328430 c90b9560-bf6c-de11-be94-00142212c4b1
402 lines
11 KiB
XML
402 lines
11 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<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
|
|
exceptions. 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>
|
|
In PHP 5.5 and later, a <literal>finally</literal> block may also be
|
|
specified after the <literal>catch</literal> blocks. Code within the
|
|
<literal>finally</literal> block will always be executed after the
|
|
<literal>try</literal> and <literal>catch</literal> blocks, regardless of
|
|
whether an exception has been thrown, and before normal execution resumes.
|
|
</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 <link linkend="spl.exceptions">built-in exceptions</link>.
|
|
</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>Exception handling with a <literal>finally</literal> block</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";
|
|
} catch (Exception $e) {
|
|
echo 'Caught exception: ', $e->getMessage(), "\n";
|
|
} finally {
|
|
echo "First finally.\n";
|
|
}
|
|
|
|
try {
|
|
echo inverse(0) . "\n";
|
|
} catch (Exception $e) {
|
|
echo 'Caught exception: ', $e->getMessage(), "\n";
|
|
} finally {
|
|
echo "Second finally.\n";
|
|
}
|
|
|
|
// Continue execution
|
|
echo 'Hello World';
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
0.2
|
|
First finally.
|
|
Caught exception: Division by zero.
|
|
Second finally.
|
|
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
|
|
fatal <constant>E_ERROR</constant> error.
|
|
</para>
|
|
</note>
|
|
<example>
|
|
<title>Extending the Exception class (PHP 5.3.0+)</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>
|
|
<note>
|
|
<para>
|
|
Versions of PHP 5, prior to PHP 5.3.0 do not support nesting of exceptions.
|
|
The following code fragment can be used as a replacement MyException class
|
|
if you wish to run this example.
|
|
</para>
|
|
<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) {
|
|
// 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";
|
|
}
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</note>
|
|
</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
|
|
-->
|