diff --git a/appendices/migration70/incompatible/error-handling.xml b/appendices/migration70/incompatible/error-handling.xml
index 37e9a31525b8..f12285f9b6cf 100644
--- a/appendices/migration70/incompatible/error-handling.xml
+++ b/appendices/migration70/incompatible/error-handling.xml
@@ -17,12 +17,12 @@
Error exceptions).
-
- A fuller description of how errors operate in PHP 7 can be found
- on the PHP 7 errors page. This
+
+ A more complete description of how errors operate in PHP 7 can be found
+ on the PHP 7 errors page. This
migration guide will merely enumerate the changes that affect backward
compatibility.
-
+
diff --git a/appendices/tokens.xml b/appendices/tokens.xml
index 7a4223faba29..30a4521916ca 100644
--- a/appendices/tokens.xml
+++ b/appendices/tokens.xml
@@ -180,7 +180,7 @@ defined('T_FN') || define('T_FN', 10001);
(int)
catch
-
+
@@ -557,7 +557,7 @@ defined('T_FN') || define('T_FN', 10001);
(int)
finally
-
+
@@ -1255,7 +1255,7 @@ defined('T_FN') || define('T_FN', 10001);
(int)
throw
-
+
@@ -1279,7 +1279,7 @@ defined('T_FN') || define('T_FN', 10001);
(int)
try
-
+
diff --git a/language/control-structures.xml b/language/control-structures.xml
index b9a6b334e9b5..437eb3ea95af 100644
--- a/language/control-structures.xml
+++ b/language/control-structures.xml
@@ -54,6 +54,9 @@
&language.control-structures.require-once;
&language.control-structures.include-once;
&language.control-structures.goto;
+ &language.control-structures.throw;
+ &language.control-structures.try-catch;
+ &language.control-structures.finally;
diff --git a/language/control-structures/finally.xml b/language/control-structures/finally.xml
new file mode 100644
index 000000000000..bcf34b5df7e9
--- /dev/null
+++ b/language/control-structures/finally.xml
@@ -0,0 +1,444 @@
+
+
+ finally
+
+
+ A &finally; block may be specified after or instead of &catch; blocks.
+ Code within the &finally; block will always be executed after the &try; and
+ &catch; blocks, even if a &return; or &yield; statement is encountered,
+ a Throwable error hasn't been caught or is rethrown.
+ It will be executed prior to resuming the normal execution flow.
+ The only exception to this rule is when a call to exit
+ is performed.
+
+
+ Throwable error handling with a &finally; block
+
+getMessage(), "\n";
+} finally {
+ echo "First finally.\n";
+}
+
+try {
+ echo inverse(0) . "\n";
+} catch (\DivisionByZeroError $e) {
+ echo 'Caught error: ', $e->getMessage(), "\n";
+} finally {
+ echo "Second finally.\n";
+}
+
+// Continue execution
+echo "Hello World\n";
+]]>
+
+ &example.outputs.8;
+
+
+
+
+
+
+ When the call stack is unwound after a Throwable error
+ has been thrown, all &finally; blocks it encounters along the way will be executed.
+ In other words, nested &finally; blocks are executed even if the
+ Throwable error is not caught by an adjacent
+ &catch; block.
+
+
+ All &finally; block will be executed
+
+
+
+ &example.outputs;
+
+
+
+
+
+
+ Interaction between a &finally; block and a &return; statement
+
+ One notable interaction is between the &finally; block and a &return; statement.
+ If a &return; statement is encountered inside either the &try; or the &catch; blocks,
+ the &finally; block will still be executed. Moreover, the &return; statement is
+ evaluated when encountered, but the result will be returned after the &finally; block
+ is executed. Additionally, if the &finally; block also contains a &return; statement,
+ the value from the &finally; block is returned.
+
+
+ Interaction between &return; in &finally; block and a previous &return;
+
+
+
+ &example.outputs;
+
+
+
+
+
+ Interaction between the &finally; block and &return;
+
+
+
+ &example.outputs;
+
+
+
+
+
+
+
+
+ Behaviour of a &finally; block in a
+ Generator
+
+
+
+ If during the traversal of a generator a Throwable
+ error is thrown, the &finally; within the generator will be executed,
+ as it is the previous element of the call stack.
+
+
+
+ &finally; block being run when an Exception
+ has been thrown
+
+
+
+
+ &example.outputs.similar;
+
+
+
+
+
+
+ It is possible to &yield; within a &finally; block but if a
+ Throwable error occurs and is not caught within
+ the &foreach; a Cannot yield from finally in a force-closed
+ generatorError is thrown.
+
+
+
+ Error when &yield;ing in &finally; block when an Exception
+ has been thrown
+
+
+
+
+ &example.outputs.similar;
+
+
+
+
+
+
+
+ Interaction between a &finally; block and a call to exit
+
+ When exit is called within a &try; or a &catch; block
+ all &finally; blocks are skipped.
+
+
+ Interaction between &finally; block and exit called in &try; block
+
+
+
+ &example.outputs;
+
+
+
+
+
+ Interaction between &finally; block and exit called in &catch; block
+
+
+
+ &example.outputs;
+
+
+
+
+
+ All &finally; blocks are skipped when exit is called
+
+
+
+ &example.outputs;
+
+
+
+
+
+
+ When exit is called within a &finally; block,
+ all other outer &finally; blocks are skipped as per the above behaviour.
+
+
+ Skipping outer &finally; block by calling exit
+
+
+
+ &example.outputs;
+
+
+
+
+
+
+ Edge case of calling exit in a &foreach; over a generator
+
+ This one edge case behaviour is highly dependent on which version of PHP
+ the code is executed.
+
+
+
+
+
+
+
+ Output of the above example prior to PHP 7.1.13, in PHP 7.2.0 and 7.2.1,
+ and as of PHP 8.0.0
+
+
+
+
+
+ Output of the above example as of PHP 7.1.14, and prior to PHP 8.0.0
+
+
+
+
+
+
+
+
diff --git a/language/control-structures/throw.xml b/language/control-structures/throw.xml
new file mode 100644
index 000000000000..f6db10d656a7
--- /dev/null
+++ b/language/control-structures/throw.xml
@@ -0,0 +1,117 @@
+
+
+ throw
+
+
+ The &throw; keyword is an expression, and may be used in any expression context,
+ which takes an instance of a Throwable object as an
+ argument.
+
+
+
+ Prior to PHP 8.0, the &throw; keyword was a statement and not an expression.
+
+
+
+ Attempting to &throw; a non-Throwable object will
+ throw an Error.
+
+
+ Throwing a non-Throwable object
+
+
+
+ &example.outputs.similar;
+
+
+
+
+
+
+ After using &throw; the normal flow of execution is halted and the call stack
+ is unwound until the global scope is reached and terminates the program with
+ a fatal error containing the stack trace indicating where the
+ Throwable object has been thrown.
+
+
+ Throwing an Exception in the global scope
+
+
+
+ &example.outputs.similar;
+
+
+
+
+
+ Throwing an Exception in a function
+
+
+
+ &example.outputs.similar;
+
+
+
+
+
+
+ As &throw; is an expression it can be used to branch out on the result
+ of another expression if its value is inappropriate.
+
+
+ Using throw as an expression
+ Only permitted in PHP 8.0.0 and later.
+
+
+
+
+
+
+ It is possible to handle a thrown Throwable by using
+ a try-catch block.
+ See the error handling
+ section for more information.
+
+
diff --git a/language/control-structures/try-catch.xml b/language/control-structures/try-catch.xml
new file mode 100644
index 000000000000..92ff872b572e
--- /dev/null
+++ b/language/control-structures/try-catch.xml
@@ -0,0 +1,226 @@
+
+
+ try-catch blocks
+
+ try
+
+
+ A &try; block delimits a segment of code which might &throw;
+ a Throwable error which one wants to possibly handle.
+ A &try; block must have at least one corresponding
+ &catch; or &finally; block.
+
+
+
+ When a Throwable error is thrown in a &try; block
+ PHP will attempt to find the first matching &catch; block to handle the
+ error, if none can be found it will unwind the call stack as usual.
+
+
+
+ catch
+
+
+ A &catch; block defines how to respond to a thrown Throwable error.
+ A &catch; block defines one or more types of Throwable
+ (most commonly Exception) it can handle, and
+ optionally a variable to which to assign the exception.
+
+
+
+ Prior to PHP 8.0.0, the variable in which to assign the
+ Throwable object was mandatory.
+
+
+
+ The first &catch; block a thrown Throwable encounters
+ that matches the class of the thrown object will handle the error before
+ resuming normal execution after the &catch; block.
+
+
+ Catching an Exception
+
+getMessage(), "\n";
+}
+
+// Continue execution
+echo "Hello World\n";
+?>
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+ As of PHP 7.1.0, a &catch; block may specify a union of
+ Throwable subclasses that the block should handle
+ using the pipe (|) character. This is useful for when
+ different exceptions from different class hierarchies are handled the same.
+
+
+ Catching a union of classes to handle
+
+ testing();
+
+?>
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+ Multiple &catch; blocks can be used to handle different classes of
+ Throwable errors in different ways.
+ Normal execution (when no error is thrown within the &try; block) will
+ continue after that last &catch; block defined in sequence.
+
+
+ Multiple catch blocks
+
+
+
+
+
+
+ Throwables can be &throw;n (or re-thrown) within a &catch; block.
+ Otherwise, execution will continue after the &catch; block that was triggered.
+
+
+ Nested Exception
+
+getMessage());
+ }
+ }
+}
+
+$foo = new Test;
+$foo->testing();
+
+?>
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+ Throwing an object within a &catch; block will not
+ be caught by an adjacent &catch; block.
+
+
+ Sequential catch blocks
+
+
+
+ &example.outputs.similar;
+
+
+
+
+
+
+
+ Omitting the caught variable
+ Only permitted in PHP 8.0.0 and later.
+
+
+]]>
+
+
+
+
diff --git a/language/error-handling.xml b/language/error-handling.xml
new file mode 100644
index 000000000000..3007b6fa151a
--- /dev/null
+++ b/language/error-handling.xml
@@ -0,0 +1,325 @@
+
+
+ Error Handling
+
+ Errors are a normal part of the development and life cycle of an application.
+ As such PHP provides multiple ways to inform and deal with errors.
+
+ PHP has two main mechanisms for reporting errors:
+
+
+
+ Throwable errors, which are further split into
+ programming errors via the Error
+ class hierarchy and recoverable errors via the
+ Exception class hierarchy.
+
+
+
+
+ Diagnostic errors which are classified into different
+ severities.
+
+
+
+
+
+ Throwable errors
+
+ Most errors in PHP are of this type.
+ A Throwable error, is an execution event which disrupts
+ the normal flow of instructions. When a Throwable error
+ is &throw;n, be that by the engine or manually, it will unwind the call stack
+ all the way up to the global scope and terminate the program with a fatal error,
+ unless it is intercepted by a &try;-&catch; block or a global exception handler.
+ All &finally; blocks it encounters along the way will be executed.
+
+
+ To throw a Throwable error from within PHP code, one
+ must use the &throw; keyword followed by an instance of the
+ Error or Exception class or
+ a subclass of one of them.
+ Trying to throw an object that does not implement Throwable will result in an
+ Error being thrown with the following message:
+ Cannot throw objects that do not implement Throwable.
+
+
+
+ The Standard PHP Library (SPL) provides
+ various built-in exceptions.
+ And it's possible to create custom exceptions by
+ extending
+ Exception.
+
+
+
+ It is possible to handle a Throwable error within PHP
+ by surrounding the code susceptible to throw an error in a &try; block.
+ A &try; block must have at least one corresponding &catch; or &finally; block.
+
+
+
+ It is not recommended to catch Error
+ objects as those signal a programming error.
+
+
+
+
+ Throwable objects cannot be cloned.
+ Attempting to clone such an
+ object will result in an Error being thrown with
+ the following message:
+ Trying to clone an uncloneable object of class Exception.
+
+
+
+
+ Global exception handler
+
+ If a Throwable object is allowed to bubble up to the
+ global scope, it will be caught by a global exception handler if one is set.
+ The set_exception_handler accepts a callable
+ which takes an exception as a parameter. It will be triggered when
+ a Throwable object bubbles up the whole call stack
+ without being caught. It acts as the ultimate &catch; for the entire program.
+ The default exception handler will stop the execution by generating a Fatal Error.
+ You can customise this behaviour by setting your own handler, and end the execution
+ of your program gracefully.
+
+
+
+
+ Extending Exceptions
+
+ A user-defined exception can be defined by extending the built-in
+ Exception class.
+
+
+ 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 used as a string.
+
+
+ Extending Exception
+
+code}]: {$this->message}\n";
+ }
+
+ public function customFunction() {
+ echo "A custom function for this type of exception\n";
+ }
+}
+
+try {
+ throw new CustomException("Something happened", 5);
+} catch (CustomException $e) {
+ echo "Caught custom exception\n";
+ echo $e;
+ $e->customFunction();
+}
+]]>
+
+ &example.outputs;
+
+
+
+
+
+
+
+ Throwable hierarchy
+
+
+
+ Throwable
+
+
+ Error
+
+
+ ArithmeticError
+
+
+ DivisionByZeroError
+
+
+
+
+ AssertionError
+
+
+ CompileError
+
+
+ ParseError
+
+
+
+
+ TypeError
+
+
+ ArgumentCountError
+
+
+
+
+ ValueError
+
+
+ UnhandledMatchError
+
+
+
+
+ Exception
+
+
+ ...
+
+
+
+
+
+
+
+
+
+
+ Diagnostic errors
+
+ Diagnostic errors, also known as traditional errors, are used to signal a
+ number of different conditions, and can be displayed and/or logged as required.
+ By default PHP will report all diagnostic errors. (Prior to PHP 8.0,
+ E_NOTICE and E_DEPRECATED
+ diagnostics were not reported by default.)
+
+
+ In contrast to Throwable errors, diagnostic errors do
+ not disrupt the normal flow of execution by default.
+ However, they can take control of execution when a handler has been set
+ with set_error_handler.
+
+
+ Which diagnostics are reported and which are ignored is controlled by the
+
+ &php.ini; directive, or at runtime by calling error_reporting.
+ It is strongly recommended that the configuration directive be set,
+ as some errors can occur before execution of your script begins.
+
+
+
+ In a development environment,
+
+ should always be set to E_ALL to be aware of and fix
+ issues raised by PHP.
+ However, in production the level of verbosity could be reduced to
+ E_ALL & ~E_NOTICE & ~E_DEPRECATED, but in many cases
+ E_ALL is still appropriate, as it may provide early
+ warning of potential issues.
+
+
+
+
+ What happens to the diagnostics depends on two further &php.ini; directives.
+ display_errors
+ controls whether the diagnostic is shown as part of the script's output.
+ This should always be disabled in a production environment, as it can include
+ confidential information such as database passwords, but is often useful to
+ enable in development, as it ensures immediate reporting of issues.
+
+
+
+ In addition to displaying errors, PHP can log diagnostics when the
+ log_errors
+ directive is enabled. This will log any diagnostic to the file or syslog
+ defined by
+ error_log.
+ This can be extremely useful in a production environment, as diagnostics are
+ logged when they occur and can then generate reports based on those logs.
+
+
+ Individual diagnostics can be suppressed using the
+ @ operator.
+
+
+
+
+ Prior to PHP 8.0.0 it was possible to suppress critical diagnostics that
+ would terminate the execution of the PHP script.
+
+
+
+
+
+ Diagnostics can be added, removed, have their severity altered or be
+ elevated to a Throwable error in between PHP versions.
+
+
+
+
+ User-defined diagnostic handler
+
+
+ If PHP's default diagnostic handling is inadequate,
+ it is possible to override the default diagnostic handler with a custom one
+ which is set by using set_error_handler.
+ Only non-fatal diagnostic can be handled this way, but they can then be
+ handled in various ways. For example, this can be used to show a custom
+ error page to the user and then report more directly than via a log, such
+ as by sending an e-mail.
+
+
+
+ Another typical usage is to elevate diagnostic errors to exceptions with
+ ErrorException.
+
+
+ Elevating diagnostic errors to exceptions
+
+
+]]>
+
+
+
+ It is important to verify that the severity is included in the current
+ list of reportable diagnostics, otherwise the
+ @ operator
+ will be broken, as an exception will be thrown for a suppressed diagnostic.
+
+
+
+
+
+
+
diff --git a/language/oop5/basic.xml b/language/oop5/basic.xml
index ea87be554544..264ca8d0290d 100644
--- a/language/oop5/basic.xml
+++ b/language/oop5/basic.xml
@@ -197,14 +197,14 @@ readonly class Foo
new
-
+
To create an instance of a class, the new keyword must
be used. An object will always be created unless the object has a
constructor defined that throws an
- exception on error. Classes
+ Exception on error. Classes
should be defined before instantiation (and in some cases this is a
requirement).
-
+
If a variable containing a string with the name of a class is used with
new, a new instance of that class will be created. If
@@ -213,10 +213,10 @@ readonly class Foo
-
+
If there are no arguments to be passed to the class's constructor,
parentheses after the class name may be omitted.
-
+
@@ -831,11 +831,11 @@ if (is_null($repository)) {
-
+
The nullsafe operator is best used when null is considered a valid and expected
possible value for a property or method return. For indicating an error,
a thrown exception is preferable.
-
+
diff --git a/language/oop5/changelog.xml b/language/oop5/changelog.xml
index 00dd1bb97d99..acfd92b6f61e 100644
--- a/language/oop5/changelog.xml
+++ b/language/oop5/changelog.xml
@@ -197,7 +197,7 @@
5.5.0
- Added: finally to handle exceptions.
+ Added: finally to handle exceptions.
@@ -255,7 +255,7 @@
Changed: Prior to 5.3.0, exceptions thrown in the
__autoload function could not be
- caught in the catch block, and
+ caught in the catch block, and
would result in a fatal error. Exceptions now thrown in the __autoload function
can be caught in the catch block, with
one provision. If throwing a custom exception, then the custom exception class must
diff --git a/language/predefined/exceptions.xml b/language/predefined/exceptions.xml
index 14a3f914d56c..c963e3d2a0e0 100644
--- a/language/predefined/exceptions.xml
+++ b/language/predefined/exceptions.xml
@@ -15,7 +15,7 @@
&language.predefined.closedgeneratorexception;
+ language/error-handling.xml. -->
&language.predefined.error;
&language.predefined.argumentcounterror;
&language.predefined.arithmeticerror;
diff --git a/manual.xml b/manual.xml
index 84c6986aa404..ba03c76218ab 100644
--- a/manual.xml
+++ b/manual.xml
@@ -52,6 +52,7 @@
&language.oop5;
&language.namespaces;
&language.enumerations;
+ &language.error-handling;
&language.errors;
&language.exceptions;
&language.fibers;
diff --git a/reference/dom/domexception.xml b/reference/dom/domexception.xml
index bcea4a042ff6..11bae6e5f574 100644
--- a/reference/dom/domexception.xml
+++ b/reference/dom/domexception.xml
@@ -25,9 +25,7 @@ FIXME: Remove me once you perform substitutions
This class is aliased as Dom\Exception in the
Dom namespace.
-
- See also .
-
+ See also .
diff --git a/reference/pdo/error-handling.xml b/reference/pdo/error-handling.xml
index 83bb4c22d0fd..64e0e72c867c 100644
--- a/reference/pdo/error-handling.xml
+++ b/reference/pdo/error-handling.xml
@@ -57,10 +57,10 @@
with less code/nesting than by running in silent mode and explicitly
checking the return value of each database call.
-
- See Exceptions for more
- information about Exceptions in PHP.
-
+
+ See for more
+ information about handling Exceptions in PHP.
+
diff --git a/reference/pdo/pdoexception.xml b/reference/pdo/pdoexception.xml
index 1d702df4c231..0a31cc05047b 100644
--- a/reference/pdo/pdoexception.xml
+++ b/reference/pdo/pdoexception.xml
@@ -8,12 +8,9 @@
&reftitle.intro;
-
- Represents an error raised by PDO. You should not throw a
- PDOException from your own code.
- See Exceptions for more
- information about Exceptions in PHP.
-
+ Represents an error raised by PDO. You should not throw a
+ PDOException from your own code.
+ See also .
@@ -58,19 +55,15 @@
errorInfo
-
- Corresponds to PDO::errorInfo or
- PDOStatement::errorInfo
-
+ Corresponds to PDO::errorInfo or
+ PDOStatement::errorInfocode
-
- SQLSTATE error code. Use
- Exception::getCode to access it.
-
+ SQLSTATE error code. Use
+ Exception::getCode to access it.
diff --git a/reference/snmp/snmpexception.xml b/reference/snmp/snmpexception.xml
index 8f91ea641c60..b6bdc283dca4 100644
--- a/reference/snmp/snmpexception.xml
+++ b/reference/snmp/snmpexception.xml
@@ -11,9 +11,8 @@
Represents an error raised by SNMP. You should not throw a
SNMPException from your own code.
- See Exceptions for more
- information about Exceptions in PHP.
+ See also .