diff --git a/appendices/migration70/incompatible/error-handling.xml b/appendices/migration70/incompatible/error-handling.xml
index 37e9a31525b8..8da24cfb0ffa 100644
--- a/appendices/migration70/incompatible/error-handling.xml
+++ b/appendices/migration70/incompatible/error-handling.xml
@@ -18,8 +18,8 @@
- 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 4294cbc1e38b..a044945ea421 100644
--- a/appendices/tokens.xml
+++ b/appendices/tokens.xml
@@ -134,7 +134,7 @@ defined('T_FN') || define('T_FN', 10001);
T_CATCHcatch
-
+ T_CLASS
@@ -387,7 +387,7 @@ defined('T_FN') || define('T_FN', 10001);
T_FINALLYfinally
-
+ T_FN
@@ -845,7 +845,7 @@ defined('T_FN') || define('T_FN', 10001);
T_THROWthrow
-
+ T_TRAIT
@@ -860,7 +860,7 @@ defined('T_FN') || define('T_FN', 10001);
T_TRYtry
-
+ T_UNSET
diff --git a/language/control-structures.xml b/language/control-structures.xml
index 8adff8a75691..683b2135a644 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..e874ba8dc08e
--- /dev/null
+++ b/language/control-structures/finally.xml
@@ -0,0 +1,445 @@
+
+
+ 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,
+ and as of PHP 8.0.0
+
+
+
+
+
+
+
+
diff --git a/language/control-structures/throw.xml b/language/control-structures/throw.xml
new file mode 100644
index 000000000000..86b165de96a3
--- /dev/null
+++ b/language/control-structures/throw.xml
@@ -0,0 +1,118 @@
+
+
+ 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..77b9df711e8d
--- /dev/null
+++ b/language/control-structures/try-catch.xml
@@ -0,0 +1,240 @@
+
+
+ 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.
+
+
+
+ It's possible to add a handler for any uncaught
+ Throwable with
+ set_exception_handler.
+ This is similar to wrapping the entire code in a &try;-&catch; block.
+
+
+
+
+ catch
+
+
+ A &catch; block defines how to respond to a thrown Throwable error.
+ A &catch; block defines one or more subclasses 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 withing a &catch; block will not
+ be caught by an adjacent &catch; block.
+
+
+ Sequential catch blocks
+
+
+
+ &example.outputs.similar;
+
+
+
+
+
+
+
+ As of PHP 8.0.0, the variable name for a caught
+ Throwable is optional.
+ If not specified, the &catch; block will still execute but will not
+ have access to the thrown object.
+
+
+ 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..a5a69a8e157f
--- /dev/null
+++ b/language/error-handling.xml
@@ -0,0 +1,323 @@
+
+
+ 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.
+ 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 is not 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 may be caught by a global exception handler if set.
+ The set_exception_handler function can set a function
+ that will be called in place of a &catch; block if no other block is invoked.
+ The effect is essentially the same as if the entire program were wrapped
+ in a &try;-&catch; block with that function as the &catch;.
+
+
+
+
+ Extending Exceptions
+
+ A user-defined exception can be defined by extending the built-in
+ Exception class.
+ To see which methods and properties are accessible within a child class
+ derived from Exception visit its page.
+
+
+ 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.
+
+
+ Which diagnostics are reported and which are ignored is controlled by the
+ error_reporting
+ &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,
+ error_reporting
+ 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 74d188eaa695..c4c5ebf9d2d9 100644
--- a/language/oop5/basic.xml
+++ b/language/oop5/basic.xml
@@ -201,7 +201,7 @@ readonly class Foo
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).
diff --git a/language/oop5/changelog.xml b/language/oop5/changelog.xml
index a57f29ba56ce..9b865e948276 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,9 +255,9 @@
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
+ can be caught in the catch block, with
one provison. If throwing a custom exception, then the custom exception class must
be available. The __autoload function may be used recursively to autoload the
custom exception class.
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/reference/dom/domexception.xml b/reference/dom/domexception.xml
index bee004bb55ca..f37578b88ad5 100644
--- a/reference/dom/domexception.xml
+++ b/reference/dom/domexception.xml
@@ -26,7 +26,7 @@ FIXME: Remove me once you perform substitutions
Dom namespace.
- See also .
+ See also .
diff --git a/reference/pdo/error-handling.xml b/reference/pdo/error-handling.xml
index 83bb4c22d0fd..c94dfcd69acd 100644
--- a/reference/pdo/error-handling.xml
+++ b/reference/pdo/error-handling.xml
@@ -58,8 +58,8 @@
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 b7d4ab81bdab..efcdb0f3da9a 100644
--- a/reference/pdo/pdoexception.xml
+++ b/reference/pdo/pdoexception.xml
@@ -12,8 +12,9 @@
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.
+
+
+ See also .
diff --git a/reference/snmp/snmpexception.xml b/reference/snmp/snmpexception.xml
index 156d570bc847..596bdb742073 100644
--- a/reference/snmp/snmpexception.xml
+++ b/reference/snmp/snmpexception.xml
@@ -12,8 +12,9 @@
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 .
diff --git a/reference/stomp/stompexception.xml b/reference/stomp/stompexception.xml
index c4f911ac5295..61f3621e3130 100644
--- a/reference/stomp/stompexception.xml
+++ b/reference/stomp/stompexception.xml
@@ -12,7 +12,10 @@
&reftitle.intro;
-Represents an error raised by the stomp extension. See Exceptions for more information about Exceptions in PHP.
+ Represents an error raised by the stomp extension.
+
+
+ See also .