From 79b0f2a75e4e0570e339ab3350b408917800c67e Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Sun, 10 Jan 2021 01:28:07 +0000 Subject: [PATCH 01/20] Refactor error pages into something more generic. This renames traditional errors to diagnostic errors Create a page about error handling in PHP describing how to handle Throwable Errors (Exceptions) and diagnostics. > Inspired from the Rust docs. Create dedicated pages for: - throw - try-catch - finally --- .../incompatible/error-handling.xml | 2 +- appendices/reserved.xml | 8 +- appendices/tokens.xml | 8 +- language/control-structures.xml | 3 + language/control-structures/finally.xml | 186 ++++++ language/control-structures/throw.xml | 118 ++++ language/control-structures/try-catch.xml | 240 +++++++ language/error-handling.xml | 304 +++++++++ language/errors.xml | 40 -- language/errors/basics.xml | 124 ---- language/errors/php7.xml | 117 ---- language/exceptions.xml | 591 ------------------ language/oop5/basic.xml | 2 +- language/oop5/changelog.xml | 6 +- language/predefined/exceptions.xml | 2 +- reference/dom/domexception.xml | 2 +- .../functions/set-exception-handler.xml | 2 +- reference/pdo/error-handling.xml | 4 +- reference/pdo/pdoexception.xml | 5 +- reference/snmp/snmpexception.xml | 2 +- 20 files changed, 873 insertions(+), 893 deletions(-) create mode 100644 language/control-structures/finally.xml create mode 100644 language/control-structures/throw.xml create mode 100644 language/control-structures/try-catch.xml create mode 100644 language/error-handling.xml delete mode 100644 language/errors.xml delete mode 100644 language/errors/basics.xml delete mode 100644 language/errors/php7.xml delete mode 100644 language/exceptions.xml diff --git a/appendices/migration70/incompatible/error-handling.xml b/appendices/migration70/incompatible/error-handling.xml index 37e9a31525b8..96bff91b237f 100644 --- a/appendices/migration70/incompatible/error-handling.xml +++ b/appendices/migration70/incompatible/error-handling.xml @@ -19,7 +19,7 @@ A fuller description of how errors operate in PHP 7 can be found - on the PHP 7 errors page. This + on the PHP 7 errors page. This migration guide will merely enumerate the changes that affect backward compatibility. diff --git a/appendices/reserved.xml b/appendices/reserved.xml index 399b84d2bc8a..5575cb663b63 100644 --- a/appendices/reserved.xml +++ b/appendices/reserved.xml @@ -55,7 +55,7 @@ case - catch + catch class @@ -134,7 +134,7 @@ final - finally + finally fn (as of PHP 7.4) @@ -236,13 +236,13 @@ switch - throw + throw trait - try + try unset 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..1389e3d41ffc --- /dev/null +++ b/language/control-structures/finally.xml @@ -0,0 +1,186 @@ + + + finally + + + A &finally; block may also be specified after or instead of &catch; blocks. + Code within the &finally; block will always be executed after the &try; and + &catch; blocks, regardless of whether a Throwable error + has been thrown, and before normal execution resumes. + + + <classname>Throwable</classname> 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. + + + All &finally; block will be executed + + + + &example.outputs; + + + + + + + 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; + + + + + + + One exception where finally blocks are skipped is if exit + is used. + + + Interaction between &finally; block and <function>exit</function> + + + + &example.outputs; + + + + + 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-<classname>Throwable</classname> 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..8178e0f3e0f1 --- /dev/null +++ b/language/control-structures/try-catch.xml @@ -0,0 +1,240 @@ + + + try-catch blocks + + try + + + A &try; block is a block which 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. + If not, 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. + + + NEEDS TITLE + + + + &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..613e93904676 --- /dev/null +++ b/language/error-handling.xml @@ -0,0 +1,304 @@ + + + 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. + + + + + + + <classname>Throwable</classname> 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. + + + + + <literal>Global exception handler</literal> + + 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 <classname>Exception</classname> + +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", $e; + $e->customFunction(); +} +]]> + + &example.outputs; + + + + + + + + <classname>Throwable</classname> 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. + + + + + 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 + + +]]> + + + + + diff --git a/language/errors.xml b/language/errors.xml deleted file mode 100644 index 0c5edd64cf82..000000000000 --- a/language/errors.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - Errors - - - Introduction - - - Sadly, no matter how careful we are when writing our code, errors are a - fact of life. PHP will report errors, warnings and notices for many common - coding and runtime problems, and knowing how to detect and handle these - errors will make debugging much easier. - - - - &language.errors.basics; - &language.errors.php7; - - - diff --git a/language/errors/basics.xml b/language/errors/basics.xml deleted file mode 100644 index 5b31f247e8d7..000000000000 --- a/language/errors/basics.xml +++ /dev/null @@ -1,124 +0,0 @@ - - - - - Basics - - - PHP reports errors in response to a number of internal error conditions. - These may be used to signal a number of different conditions, and can be - displayed and/or logged as required. - - - - Every error that PHP generates includes a type. A - list of these error types is available, - along with a short description of their behaviour and how they can be - caused. - - - - Handling errors with PHP - - - If no error handler is set, then PHP will handle any errors that occur - according to its configuration. Which errors 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, however, as some errors can occur before - execution of your script begins. - - - - In a development environment, you should always set - error_reporting - to E_ALL, as you need to be aware of and fix the - issues raised by PHP. In production, you may wish to set this to a less - verbose level such as - E_ALL & ~E_NOTICE & ~E_DEPRECATED, but - in many cases E_ALL is also appropriate, as it may - provide early warning of potential issues. - - - - What PHP does with these errors depends on two further php.ini directives. - display_errors - controls whether the error 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 errors when the - log_errors - directive is enabled. This will log any errors to the file or syslog - defined by - error_log. This - can be extremely useful in a production environment, as you can log errors - that occur and then generate reports based on those errors. - - - - - User error handlers - - - If PHP's default error handling is inadequate, you can also handle many - types of error with your own custom error handler by installing it with - set_error_handler. While some error types cannot be - handled this way, those that can be handled can then be handled in the way - that your script sees fit: 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. - - - - - &reftitle.changelog; - - - - - &Version; - &Description; - - - - - 8.5.0 - - Fatal errors (such as an exceeded maximum execution time) now include - a stack trace in their error message. - - - - - - - - - - - diff --git a/language/errors/php7.xml b/language/errors/php7.xml deleted file mode 100644 index 55400297825c..000000000000 --- a/language/errors/php7.xml +++ /dev/null @@ -1,117 +0,0 @@ - - - - - Errors in PHP 7 - - - PHP 7 changes how most errors are reported by PHP. Instead of reporting - errors through the traditional error reporting mechanism used by PHP 5, most - errors are now reported by throwing Error exceptions. - - - - As with normal exceptions, these Error exceptions - will bubble up until they reach the first matching - catch - block. If there are no matching blocks, then any default exception handler - installed with set_exception_handler will be called, - and if there is no default exception handler, then the exception will be - converted to a fatal error and will be handled like a traditional error. - - - - As the Error hierarchy does not inherit from - Exception, code that uses - catch (Exception $e) { ... } blocks to handle uncaught - exceptions in PHP 5 will find that these Errors are - not caught by these blocks. Either a catch (Error $e) { ... } - block or a set_exception_handler handler is required. - - - - <classname>Error</classname> hierarchy - - - - Throwable - - - Error - - - ArithmeticError - - - DivisionByZeroError - - - - - AssertionError - - - CompileError - - - ParseError - - - - - TypeError - - - ArgumentCountError - - - - - ValueError - - - UnhandledMatchError - - - FiberError - - - RequestParseBodyException - - - - - Exception - - - ... - - - - - - - - - - - diff --git a/language/exceptions.xml b/language/exceptions.xml deleted file mode 100644 index c284e26c36d5..000000000000 --- a/language/exceptions.xml +++ /dev/null @@ -1,591 +0,0 @@ - - - - Exceptions - - See also the Exception class - - - PHP has an exception model similar to that of other programming - languages. An exception can be &throw;n, and caught ("&catch;ed") within - PHP. Code may be surrounded in a &try; block, to facilitate the catching - of potential exceptions. Each &try; must have at least one corresponding - &catch; or &finally; block. - - - If an exception is thrown and its current function scope has no &catch; - block, the exception will "bubble up" the call stack to the calling - function until it finds a matching &catch; block. All &finally; blocks it encounters - along the way will be executed. If the call stack is unwound all the way to the - global scope without encountering a matching &catch; block, the program will - terminate with a fatal error unless a global exception handler has been set. - - - The thrown object must be an &instanceof; Throwable. - Trying to throw an object that is not will result in a PHP Fatal Error. - - - As of PHP 8.0.0, the &throw; keyword is an expression and may be used in any expression - context. In prior versions it was a statement and was required to be on its own line. - - - - <literal>catch</literal> - - A &catch; block defines how to respond to a thrown exception. A &catch; - block defines one or more types of exception or error it can handle, and - optionally a variable to which to assign the exception. (The variable was - required prior to PHP 8.0.0.) The first &catch; block a thrown exception - or error encounters that matches the type of the thrown object will handle - the object. - - - Multiple &catch; blocks can be used to catch different classes of - exceptions. Normal execution (when no exception is thrown within the &try; - block) will continue after that last &catch; block defined in sequence. - Exceptions can be &throw;n (or re-thrown) within a &catch; block. If not, - execution will continue after the &catch; block that was triggered. - - - When an exception is thrown, code following the statement will not be - executed, and PHP will attempt to find the first matching &catch; block. - If an exception is not caught, a PHP Fatal Error will be issued with an - "Uncaught Exception ..." message, unless a handler has - been defined with set_exception_handler. - - - As of PHP 7.1.0, a &catch; block may specify multiple exceptions - using the pipe (|) character. This is useful for when - different exceptions from different class hierarchies are handled the - same. - - - As of PHP 8.0.0, the variable name for a caught exception is optional. - If not specified, the &catch; block will still execute but will not - have access to the thrown object. - - - - - <literal>finally</literal> - - A &finally; block may also be specified after or - instead of &catch; blocks. Code within the &finally; block will always be - executed after the &try; and &catch; blocks, regardless of whether an - exception has been thrown, and before normal execution resumes. - - - 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. - - - Another notable interaction is between an exception thrown from within a &try; block, - and an exception thrown from within a &finally; block. If both blocks throw an exception, - then the exception thrown from the &finally; block will be the one that is propagated, - and the exception thrown from the &try; block will be used as its previous exception. - - - - - Global exception handler - - If an exception 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;. - - - - - &reftitle.notes; - - - - Internal PHP functions mainly use - Error reporting, only modern - Object-oriented - extensions use exceptions. However, errors can be easily translated to - exceptions with ErrorException. - This technique only works with non-fatal errors, however. - - - Converting error reporting to exceptions - - - - - - - - The Standard PHP Library (SPL) provides - a good number of built-in - exceptions. - - - - - - &reftitle.examples; - - - Throwing an Exception - -getMessage(), "\n"; -} - -// Continue execution -echo "Hello World\n"; -]]> - - &example.outputs; - - - - - - Exception handling with a &finally; block - -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\n"; -]]> - - &example.outputs; - - - - - - Interaction between the &finally; block and &return; - - - - &example.outputs; - - - - - - Nested Exception - -getMessage()); - } - } -} - -$foo = new Test; -$foo->testing(); -]]> - - &example.outputs; - - - - - - Multi catch exception handling - -testing(); -]]> - - &example.outputs; - - - - - - Omitting the caught variable - Only permitted in PHP 8.0.0 and later. - - - - &example.outputs; - - - - - - Throw as an expression - Only permitted in PHP 8.0.0 and later. - -getMessage(); -} -]]> - - &example.outputs; - - - - - - Exception in try and in finally - -getMessage(), - $e->getPrevious()->getMessage(), - $e->getPrevious()->getPrevious()->getMessage(), - $e->getPrevious()->getPrevious()->getPrevious()->getMessage(), - ); -} -]]> - - &example.outputs; - - - - - - - - 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. - - - 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 presented as a string. - - - - Exceptions cannot be cloned. Attempting to clone an exception throws an - Error, even if a subclass declares its own - __clone() method. - - - - Extending the Exception class - - 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; - } - } -} - - -echo "# Example 1\n"; -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\n"; -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\n"; -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\n"; -try { - $o = new TestException(); -} catch (Exception $e) { // Skipped, no exception - echo "Default Exception caught\n", $e; -} - -// Continue execution -var_dump($o); // TestException -]]> - - - - - - - diff --git a/language/oop5/basic.xml b/language/oop5/basic.xml index ea87be554544..05d1a256b90a 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 9580aecbd184..bccee0a60328 100644 --- a/language/oop5/changelog.xml +++ b/language/oop5/changelog.xml @@ -213,7 +213,7 @@ 5.5.0 - Added: finally to handle exceptions. + Added: finally to handle exceptions. @@ -271,9 +271,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 provision. 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 bcea4a042ff6..3a041f237752 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/errorfunc/functions/set-exception-handler.xml b/reference/errorfunc/functions/set-exception-handler.xml index df06f4462c14..107f531f7c2a 100644 --- a/reference/errorfunc/functions/set-exception-handler.xml +++ b/reference/errorfunc/functions/set-exception-handler.xml @@ -149,7 +149,7 @@ echo "Not Executed\n"; restore_exception_handler restore_error_handler error_reporting - Exceptions + Exceptions 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 1d702df4c231..40b25c5f4c87 100644 --- a/reference/pdo/pdoexception.xml +++ b/reference/pdo/pdoexception.xml @@ -11,8 +11,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 8f91ea641c60..36834097cae9 100644 --- a/reference/snmp/snmpexception.xml +++ b/reference/snmp/snmpexception.xml @@ -11,7 +11,7 @@ Represents an error raised by SNMP. You should not throw a SNMPException from your own code. - See Exceptions for more + See Exceptions for more information about Exceptions in PHP. From fb74194fb5f6c6cfbfdb464fa78401beed826ba6 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Thu, 4 Feb 2021 19:04:00 +0000 Subject: [PATCH 02/20] Clarify finally and return example --- language/control-structures/finally.xml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/language/control-structures/finally.xml b/language/control-structures/finally.xml index 1389e3d41ffc..3a00f565dc5c 100644 --- a/language/control-structures/finally.xml +++ b/language/control-structures/finally.xml @@ -94,8 +94,10 @@ Outer finally From 9b92fa24cc1e8a43d8563fd69df6d71da9d5a117 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Thu, 4 Feb 2021 19:15:22 +0000 Subject: [PATCH 03/20] Expand finally and exit() interaction section --- language/control-structures/finally.xml | 85 ++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 3 deletions(-) diff --git a/language/control-structures/finally.xml b/language/control-structures/finally.xml index 3a00f565dc5c..4df105227b61 100644 --- a/language/control-structures/finally.xml +++ b/language/control-structures/finally.xml @@ -167,12 +167,15 @@ finally catch + + Interaction between a &finally; block and a call to <function>exit</function> + - One exception where finally blocks are skipped is if exit - is used. + When exit is called within a &try; or a &catch; block + all &finally; blocks are skipped. - Interaction between &finally; block and <function>exit</function> + Interaction between &finally; block and <function>exit</function> called in &try; block + + + + Interaction between &finally; block and <function>exit</function> called in &catch; block + + + + &example.outputs; + + + + + + All &finally; block and skipped when <function>exit</function> 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 <function>exit</function> + + + + &example.outputs; + + From b4d26dd8ecf019365f074aa5994f46655b3b87d8 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Thu, 4 Feb 2021 19:24:00 +0000 Subject: [PATCH 04/20] Indent --- language/control-structures/finally.xml | 80 ++++++++++++------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/language/control-structures/finally.xml b/language/control-structures/finally.xml index 4df105227b61..449017b217e1 100644 --- a/language/control-structures/finally.xml +++ b/language/control-structures/finally.xml @@ -169,14 +169,13 @@ finally catch Interaction between a &finally; block and a call to <function>exit</function> - - - When exit is called within a &try; or a &catch; block - all &finally; blocks are skipped. - - - Interaction between &finally; block and <function>exit</function> called in &try; block - + + When exit is called within a &try; or a &catch; block + all &finally; blocks are skipped. + + + Interaction between &finally; block and <function>exit</function> called in &try; block + - - &example.outputs; - + + &example.outputs; + - - - - Interaction between &finally; block and <function>exit</function> called in &catch; block - + + + + Interaction between &finally; block and <function>exit</function> called in &catch; block + - - &example.outputs; + + &example.outputs; - - - - All &finally; block and skipped when <function>exit</function> is called - + + + + All &finally; block and skipped when <function>exit</function> is called + - - &example.outputs; - + + &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 <function>exit</function> - + + 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 <function>exit</function> + - - &example.outputs; - + + &example.outputs; + - - + + + From 68fbe01626d69e39da3bf896119e581ed44ab521 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Thu, 4 Feb 2021 19:25:35 +0000 Subject: [PATCH 05/20] Make intereaction between return and finally a section --- language/control-structures/finally.xml | 51 +++++++++++++------------ 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/language/control-structures/finally.xml b/language/control-structures/finally.xml index 449017b217e1..46394ea5e060 100644 --- a/language/control-structures/finally.xml +++ b/language/control-structures/finally.xml @@ -79,17 +79,19 @@ Outer finally - - 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; - + + 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; - + + &example.outputs; + - - - - Interaction between the &finally; block and &return; - + + + + Interaction between the &finally; block and &return; + - - &example.outputs; - + + &example.outputs; + - - + + + Interaction between a &finally; block and a call to <function>exit</function> From fe0fa15e8be40bdd537dbedf0988adacccced1a8 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Thu, 4 Feb 2021 23:20:13 +0000 Subject: [PATCH 06/20] Add an initial section about yield and finally --- language/control-structures/finally.xml | 111 ++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/language/control-structures/finally.xml b/language/control-structures/finally.xml index 46394ea5e060..33fa19933ba0 100644 --- a/language/control-structures/finally.xml +++ b/language/control-structures/finally.xml @@ -170,6 +170,117 @@ finally catch + + + 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 <classname>Exception</classname> + has been thrown + + + + + &example.outputs.similar; + + + + + + + It is possible to &yield; within a &finally; block but if a + Throwable error occurs and is not &catch;ed within + the &foreach; a Cannot yield from finally in a force-closed + generator Error is thrown. + + + + Error when &yield;ing in &finally; block when an <classname>Exception</classname> + has been thrown + + + + + &example.outputs.similar; + + + + + + + + + Interaction between a &finally; block and a call to <function>exit</function> From 0cb3660f8f61eb17928e770ebf1d64add842d16f Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Thu, 4 Feb 2021 23:33:15 +0000 Subject: [PATCH 07/20] Clarify what call-stack unwinding means --- language/control-structures/finally.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/language/control-structures/finally.xml b/language/control-structures/finally.xml index 33fa19933ba0..98abff3ad4bf 100644 --- a/language/control-structures/finally.xml +++ b/language/control-structures/finally.xml @@ -52,6 +52,9 @@ Hello World 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 From e4af9cc58380a6e1afe8aa14e0ec54f6fdbebe42 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Thu, 4 Feb 2021 23:34:51 +0000 Subject: [PATCH 08/20] Use variable in catch statement Usage without it is explained in the following section --- language/control-structures/try-catch.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/language/control-structures/try-catch.xml b/language/control-structures/try-catch.xml index 8178e0f3e0f1..7c6183883e6d 100644 --- a/language/control-structures/try-catch.xml +++ b/language/control-structures/try-catch.xml @@ -180,7 +180,7 @@ string(4) "foo!" NEEDS TITLE - Date: Thu, 4 Feb 2021 23:41:49 +0000 Subject: [PATCH 09/20] Add error_reporting() check when using a custom error handler --- language/error-handling.xml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/language/error-handling.xml b/language/error-handling.xml index 613e93904676..04d09dad7c71 100644 --- a/language/error-handling.xml +++ b/language/error-handling.xml @@ -291,13 +291,24 @@ A custom function for this type of exception ]]> + + + 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. + + + From 7bd4eb6e2b6d6ff012a514f2f3f6376c93478769 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Fri, 5 Feb 2021 00:12:08 +0000 Subject: [PATCH 10/20] Cleanup docs related to @ operator Also fix part of the set_error_handler() docs --- language/error-handling.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/language/error-handling.xml b/language/error-handling.xml index 04d09dad7c71..9ba168fe274f 100644 --- a/language/error-handling.xml +++ b/language/error-handling.xml @@ -261,6 +261,13 @@ A custom function for this type of exception @ 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 From 581d85422b29c6726e218dcd740f88951a98f708 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Thu, 18 Feb 2021 16:41:23 +0000 Subject: [PATCH 11/20] Nits --- appendices/migration70/incompatible/error-handling.xml | 2 +- language/control-structures/try-catch.xml | 2 +- language/error-handling.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/appendices/migration70/incompatible/error-handling.xml b/appendices/migration70/incompatible/error-handling.xml index 96bff91b237f..8da24cfb0ffa 100644 --- a/appendices/migration70/incompatible/error-handling.xml +++ b/appendices/migration70/incompatible/error-handling.xml @@ -18,7 +18,7 @@ - A fuller description of how errors operate in PHP 7 can be found + 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/language/control-structures/try-catch.xml b/language/control-structures/try-catch.xml index 7c6183883e6d..141348a4024d 100644 --- a/language/control-structures/try-catch.xml +++ b/language/control-structures/try-catch.xml @@ -178,7 +178,7 @@ string(4) "foo!" be caught by an adjacent &catch; block. - NEEDS TITLE + Sequential catch blocks 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, + By default PHP will report all diagnostic errors. (Prior to PHP 8.0, E_NOTICE and E_DEPRECATED - diagnostics were not reported by default). + diagnostics were not reported by default.) In contrast to Throwable errors, diagnostic errors do From 118df496ab8054b8a912e65bc76fb30e0c86d9e4 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Thu, 18 Feb 2021 16:55:27 +0000 Subject: [PATCH 12/20] Front load logic of finally behaviour with various other bits --- language/control-structures/finally.xml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/language/control-structures/finally.xml b/language/control-structures/finally.xml index 98abff3ad4bf..4685f6865435 100644 --- a/language/control-structures/finally.xml +++ b/language/control-structures/finally.xml @@ -5,8 +5,11 @@ A &finally; block may also be specified after or instead of &catch; blocks. Code within the &finally; block will always be executed after the &try; and - &catch; blocks, regardless of whether a Throwable error - has been thrown, and before normal execution resumes. + &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. <classname>Throwable</classname> error handling with a &finally; block @@ -174,8 +177,10 @@ finally catch - - Behaviour of a &finally; block in a Generator + + Behaviour of a &finally; block in a + <link linkend="language.generators">Generator</link> + If during the traversal of a generator a Throwable From dca00959db98af01e0fbf0da59a7648e67652da4 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Thu, 18 Feb 2021 17:09:04 +0000 Subject: [PATCH 13/20] Document weird finally exit and generator edge case --- language/control-structures/finally.xml | 60 ++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/language/control-structures/finally.xml b/language/control-structures/finally.xml index 4685f6865435..4840a61473a0 100644 --- a/language/control-structures/finally.xml +++ b/language/control-structures/finally.xml @@ -282,11 +282,6 @@ Stack trace: ]]> - - - @@ -391,5 +386,60 @@ inner finally ]]> + + + Edge case of calling <function>exit</function> 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 + + + + + + From ec018a77cb7f82e3e78685d3e4f453958c806586 Mon Sep 17 00:00:00 2001 From: Anna Filina Date: Tue, 17 Aug 2021 09:24:05 -0400 Subject: [PATCH 14/20] Add missing parenthesis Co-authored-by: George Peter Banyard --- language/error-handling.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/language/error-handling.xml b/language/error-handling.xml index 639b082c7f66..7b78f968a949 100644 --- a/language/error-handling.xml +++ b/language/error-handling.xml @@ -298,7 +298,7 @@ A custom function for this type of exception Date: Tue, 29 Sep 2026 08:23:36 +0200 Subject: [PATCH 15/20] Update links to the removed exception and error pages Point the throw, try, catch and finally entities and the remaining references to the anchors of the new Error handling and control structure pages, and include the new chapter in manual.xml. --- entities/entities.php.ent | 8 ++++---- language/operators/precedence.xml | 2 +- manual.xml | 3 +-- reference/errorfunc/functions/get-exception-handler.xml | 2 +- reference/pdo/connections.xml | 2 +- reference/stomp/stompexception.xml | 2 +- 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/entities/entities.php.ent b/entities/entities.php.ent index 8736cb6e803d..f83651342e48 100644 --- a/entities/entities.php.ent +++ b/entities/entities.php.ent @@ -21,7 +21,7 @@ There are a few tossed near and there. intcallbackmixedamixedb -catch +catch const @@ -29,7 +29,7 @@ There are a few tossed near and there. false -finally +finally float @@ -71,11 +71,11 @@ There are a few tossed near and there. string -throw +throw true -try +try use diff --git a/language/operators/precedence.xml b/language/operators/precedence.xml index 9d4f02925ef5..2dfbdd8963a3 100644 --- a/language/operators/precedence.xml +++ b/language/operators/precedence.xml @@ -320,7 +320,7 @@ (n/a) throw - throw + throw diff --git a/manual.xml b/manual.xml index 84c6986aa404..f393b9f67120 100644 --- a/manual.xml +++ b/manual.xml @@ -52,8 +52,7 @@ &language.oop5; &language.namespaces; &language.enumerations; - &language.errors; - &language.exceptions; + &language.error-handling; &language.fibers; &language.generators; &language.attributes; diff --git a/reference/errorfunc/functions/get-exception-handler.xml b/reference/errorfunc/functions/get-exception-handler.xml index 919e03687b31..a24d27f44649 100644 --- a/reference/errorfunc/functions/get-exception-handler.xml +++ b/reference/errorfunc/functions/get-exception-handler.xml @@ -91,7 +91,7 @@ if (!function_exists('get_exception_handler')) { restore_exception_handler restore_error_handler error_reporting - Exceptions + Exceptions diff --git a/reference/pdo/connections.xml b/reference/pdo/connections.xml index 6602616cc3b4..ef5f05fc2106 100644 --- a/reference/pdo/connections.xml +++ b/reference/pdo/connections.xml @@ -45,7 +45,7 @@ try { - Just like any other exception, + Just like any other exception, PDOException could be caught either explicitly, via a &catch; statement, or implicitly via set_exception_handler. Otherwise, the default behaviour of converting an uncaught exception to a diff --git a/reference/stomp/stompexception.xml b/reference/stomp/stompexception.xml index b2fb456efbc3..8e679ea2da6a 100644 --- a/reference/stomp/stompexception.xml +++ b/reference/stomp/stompexception.xml @@ -11,7 +11,7 @@
&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 Exceptions for more information about Exceptions in PHP.
From 7f032c48ab61e9d3eac2be061ae749a79d47e074 Mon Sep 17 00:00:00 2001 From: Louis-Arnaud Date: Tue, 29 Sep 2026 08:23:36 +0200 Subject: [PATCH 16/20] Port master changes to the new error handling pages Restore the $Revision$ markers, mark the chapter as interactive, and carry over the changes made to the removed pages since the branch was created: exception chaining with finally, explicit nullable type in the custom exception example, clone warning, FiberError in the hierarchy, 8.5.0 changelog entry, missing example outputs and the runnable throw expression example. --- language/control-structures/finally.xml | 42 +++++++++++++++++++++++ language/control-structures/throw.xml | 20 +++++++++-- language/control-structures/try-catch.xml | 15 ++++---- language/error-handling.xml | 38 +++++++++++++++++--- 4 files changed, 102 insertions(+), 13 deletions(-) diff --git a/language/control-structures/finally.xml b/language/control-structures/finally.xml index 4840a61473a0..23cd49bb3759 100644 --- a/language/control-structures/finally.xml +++ b/language/control-structures/finally.xml @@ -1,4 +1,5 @@ + finally @@ -176,6 +177,47 @@ finally catch + + Interaction between a &finally; block and an exception thrown in a &try; block + + If both the &try; block and the &finally; block throw an exception, + the exception thrown from the &finally; block is the one that is propagated, + and the exception thrown from the &try; block will be used as its previous exception. + + + Exception in try and in finally + +getMessage(), + $e->getPrevious()->getMessage(), + $e->getPrevious()->getPrevious()->getMessage(), + $e->getPrevious()->getPrevious()->getPrevious()->getMessage(), + ); +} +]]> + + &example.outputs; + + + + + + Behaviour of a &finally; block in a diff --git a/language/control-structures/throw.xml b/language/control-structures/throw.xml index 86b165de96a3..fc90f33b3d70 100644 --- a/language/control-structures/throw.xml +++ b/language/control-structures/throw.xml @@ -1,4 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- $Revision$ --> <sect1 xml:id="control-structures.throw" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>throw @@ -101,12 +102,27 @@ Stack trace: getMessage(); +} ]]> + &example.outputs; + + + diff --git a/language/control-structures/try-catch.xml b/language/control-structures/try-catch.xml index 141348a4024d..b3703950922e 100644 --- a/language/control-structures/try-catch.xml +++ b/language/control-structures/try-catch.xml @@ -1,4 +1,5 @@ + try-catch blocks @@ -58,7 +59,6 @@ try { // Continue execution echo "Hello World\n"; -?> ]]> &example.outputs; @@ -98,8 +98,6 @@ class Test { $foo = new Test; $foo->testing(); - -?> ]]> &example.outputs; @@ -118,7 +116,7 @@ string(11) "MyException" Multiple catch blocks - + testing(); - -?> ]]> &example.outputs; @@ -232,9 +228,14 @@ try { } catch (SpecificException) { print "A SpecificException was thrown, but we don't care about the details."; } -?> ]]> + &example.outputs; + + + diff --git a/language/error-handling.xml b/language/error-handling.xml index 7b78f968a949..26cd4ed9b906 100644 --- a/language/error-handling.xml +++ b/language/error-handling.xml @@ -1,6 +1,10 @@ - + + Error Handling + + See also the Exception class + 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. @@ -68,7 +72,8 @@ Throwable objects cannot be cloned. Attempting to clone such an - object will result in an Error being thrown with + object throws an Error, even if a subclass declares + its own __clone() method, with the following message: Trying to clone an uncloneable object of class Exception. @@ -110,7 +115,7 @@ class CustomException extends Exception { // Redefine the constructor so message isn't optional - public function __construct($message, $code = 0, Exception $previous = null) { + public function __construct($message, $code = 0, ?Throwable $previous = null) { // some code // Ensure everything is assigned properly @@ -189,6 +194,9 @@ A custom function for this type of exception UnhandledMatchError + + FiberError + @@ -304,7 +312,6 @@ function exceptions_error_handler($severity, $message, $filename, $lineno) { } set_error_handler('exceptions_error_handler'); -?> ]]> @@ -318,5 +325,28 @@ set_error_handler('exceptions_error_handler'); + + + &reftitle.changelog; + + + + + &Version; + &Description; + + + + + 8.5.0 + + Fatal errors (such as an exceeded maximum execution time) now include + a stack trace in their error message. + + + + + + From d6059009e51ba87e171154391e9c456ed591f269 Mon Sep 17 00:00:00 2001 From: Louis-Arnaud Date: Tue, 29 Sep 2026 08:52:03 +0200 Subject: [PATCH 17/20] Fix inaccuracies in the error handling pages Correct the outputs of the finally examples, the claim that exit is the only case skipping a finally block, the version ranges of the exit and generator edge case, and the statements about the global exception handler and about fatal diagnostics. --- language/control-structures/finally.xml | 17 +++++++++-------- language/error-handling.xml | 20 +++++++++++--------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/language/control-structures/finally.xml b/language/control-structures/finally.xml index 23cd49bb3759..86062ce4bc3f 100644 --- a/language/control-structures/finally.xml +++ b/language/control-structures/finally.xml @@ -9,8 +9,9 @@ &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. + The only exceptions to this rule are when the script is terminated abruptly, + such as by a call to exit or by a fatal error + (for example when the maximum execution time is exceeded).
<classname>Throwable</classname> error handling with a &finally; block @@ -46,7 +47,7 @@ echo "Hello World\n"; @@ -133,10 +134,10 @@ echo testReturnCatch(), "\n"; @@ -463,7 +464,7 @@ try { ]]> - Output of the above example prior to PHP 7.1.13, in PHP 7.2.0 and 7.2.1, + Output of the above example prior to PHP 7.1.14, in PHP 7.2.0 and 7.2.1, and as of PHP 8.0.0 @@ -473,8 +474,8 @@ inner finally ]]> - 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 + Output of the above example as of PHP 7.1.14 and 7.2.2, + and prior to PHP 8.0.0 <classname>Throwable</classname> errors - Most errors in PHP are of this type. - A Throwable error, is an execution event which disrupts + 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. @@ -78,7 +77,7 @@ Trying to clone an uncloneable object of class Exception.
- + <literal>Global exception handler</literal> @@ -86,8 +85,8 @@ 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;. + Unlike a &catch; block, execution does not resume afterwards: the script + terminates once the handler returns. @@ -223,8 +222,9 @@ A custom function for this type of exception diagnostics were not reported by default.) - In contrast to Throwable errors, diagnostic errors do - not disrupt the normal flow of execution. + In contrast to Throwable errors, most diagnostic + errors do not disrupt the normal flow of execution. + Fatal diagnostics, such as E_ERROR, terminate the script. Which diagnostics are reported and which are ignored is controlled by the @@ -290,8 +290,10 @@ A custom function for this type of exception 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 + Some diagnostics, such as E_ERROR and + E_PARSE, cannot be handled this way (see + set_error_handler for the full list), but the others + 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. From 843860320f28be8d4951a5738a741c0b59eb6eb1 Mon Sep 17 00:00:00 2001 From: Louis-Arnaud Date: Tue, 29 Sep 2026 09:01:47 +0200 Subject: [PATCH 18/20] Use exceptionname for exception classes and leave the stomp page untouched The stomp extension is migrating to doc-extensions, so its page is restored to master. The old language.exceptions anchor is kept as an alias so that the existing reference from that page still resolves. --- language/control-structures/finally.xml | 18 +++--- language/control-structures/throw.xml | 12 ++-- language/control-structures/try-catch.xml | 24 ++++---- language/error-handling.xml | 71 ++++++++++++----------- reference/stomp/stompexception.xml | 2 +- 5 files changed, 64 insertions(+), 63 deletions(-) diff --git a/language/control-structures/finally.xml b/language/control-structures/finally.xml index 86062ce4bc3f..997643fc9ab6 100644 --- a/language/control-structures/finally.xml +++ b/language/control-structures/finally.xml @@ -7,14 +7,14 @@ A &finally; block may also 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. + a Throwable error hasn't been caught or is rethrown. It will be executed prior to resuming the normal execution flow. The only exceptions to this rule are when the script is terminated abruptly, such as by a call to exit or by a fatal error (for example when the maximum execution time is exceeded). - <classname>Throwable</classname> error handling with a &finally; block + <exceptionname>Throwable</exceptionname> error handling with a &finally; block - When the call stack is unwound after a Throwable error + 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 + Throwable error is not caught by an adjacent &catch; block. @@ -226,13 +226,13 @@ string(6) "Fourth" - If during the traversal of a generator a Throwable + 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 <classname>Exception</classname> + &finally; block being run when an <exceptionname>Exception</exceptionname> has been thrown @@ -272,13 +272,13 @@ outer catch It is possible to &yield; within a &finally; block but if a - Throwable error occurs and is not &catch;ed within + Throwable error occurs and is not &catch;ed within the &foreach; a Cannot yield from finally in a force-closed - generator Error is thrown. + generator Error is thrown. - Error when &yield;ing in &finally; block when an <classname>Exception</classname> + Error when &yield;ing in &finally; block when an <exceptionname>Exception</exceptionname> has been thrown diff --git a/language/control-structures/throw.xml b/language/control-structures/throw.xml index fc90f33b3d70..4f8e96bf1f2c 100644 --- a/language/control-structures/throw.xml +++ b/language/control-structures/throw.xml @@ -5,7 +5,7 @@ The &throw; keyword is an expression, and may be used in any expression context, - which takes an instance of a Throwable object as an + which takes an instance of a Throwable object as an argument. @@ -14,11 +14,11 @@ - Attempting to &throw; a non-Throwable object will - throw an Error. + Attempting to &throw; a non-Throwable object will + throw an Error. - Throwing a non-<classname>Throwable</classname> object + Throwing a non-<exceptionname>Throwable</exceptionname> object Throwable object has been thrown. + Throwable object has been thrown. Throwing an Exception in the global scope @@ -126,7 +126,7 @@ It did not work - It is possible to handle a thrown Throwable by using + 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 index b3703950922e..1d1b6d1a629c 100644 --- a/language/control-structures/try-catch.xml +++ b/language/control-structures/try-catch.xml @@ -7,20 +7,20 @@ A &try; block is a block which delimits a segment of code which might &throw; - a Throwable error which one wants to possibly handle. + 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 + 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 + Throwable with set_exception_handler. This is similar to wrapping the entire code in a &try;-&catch; block. @@ -30,19 +30,19 @@ 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 + 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. + Throwable object was mandatory. - The first &catch; block a thrown Throwable encounters + 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. @@ -72,7 +72,7 @@ Hello World As of PHP 7.1.0, a &catch; block may specify a union of - Throwable subclasses that the block should handle + 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. @@ -110,7 +110,7 @@ string(11) "MyException" Multiple &catch; blocks can be used to handle different classes of - Throwable errors in different ways. + 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. @@ -131,7 +131,7 @@ try { - Throwables can be &throw;n (or re-thrown) within a &catch; block. + Throwables can be &throw;n (or re-thrown) within a &catch; block. If not, execution will continue after the &catch; block that was triggered. @@ -206,7 +206,7 @@ Stack trace: As of PHP 8.0.0, the variable name for a caught - Throwable is optional. + Throwable is optional. If not specified, the &catch; block will still execute but will not have access to the thrown object. diff --git a/language/error-handling.xml b/language/error-handling.xml index 1e77410d5191..c2cb8b657a42 100644 --- a/language/error-handling.xml +++ b/language/error-handling.xml @@ -14,10 +14,10 @@ - Throwable errors, which are further split into - programming errors via the Error + Throwable errors, which are further split into + programming errors via the Error class hierarchy and recoverable errors via the - Exception class hierarchy. + Exception class hierarchy. @@ -30,21 +30,22 @@ - <classname>Throwable</classname> errors + <exceptionname>Throwable</exceptionname> errors + - A Throwable error is an execution event which disrupts - the normal flow of instructions. When a Throwable error + 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 + 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 + 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: + Error being thrown with the following message: Cannot throw objects that do not implement Throwable. @@ -53,25 +54,25 @@ various built-in exceptions. And it's possible to create custom exceptions by extending - Exception. + Exception. - It is possible to handle a Throwable error within PHP + 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 + It is not recommended to catch Error objects as those signal a programming error. - Throwable objects cannot be cloned. + Throwable objects cannot be cloned. Attempting to clone such an - object throws an Error, even if a subclass declares + object throws an Error, even if a subclass declares its own __clone() method, with the following message: Trying to clone an uncloneable object of class Exception. @@ -81,7 +82,7 @@ <literal>Global exception handler</literal> - If a Throwable object is allowed to bubble up to the + 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. @@ -94,12 +95,12 @@ Extending Exceptions A User defined exception can be defined by extending the built-in - Exception class. + Exception class. To see which methods and properties are accessible within a child class - derived from Exception visit its page. + derived from Exception visit its page. - If a class extends the built-in Exception class and + 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. @@ -107,7 +108,7 @@ to provide a custom output when the object is used as a string. - Extending <classname>Exception</classname> + Extending <exceptionname>Exception</exceptionname> - <classname>Throwable</classname> hierarchy + <exceptionname>Throwable</exceptionname> hierarchy - Throwable + Throwable - Error + Error - ArithmeticError + ArithmeticError - DivisionByZeroError + DivisionByZeroError - AssertionError + AssertionError - CompileError + CompileError - ParseError + ParseError - TypeError + TypeError - ArgumentCountError + ArgumentCountError - ValueError + ValueError - UnhandledMatchError + UnhandledMatchError - FiberError + FiberError - Exception + Exception ... @@ -222,7 +223,7 @@ A custom function for this type of exception diagnostics were not reported by default.) - In contrast to Throwable errors, most diagnostic + In contrast to Throwable errors, most diagnostic errors do not disrupt the normal flow of execution. Fatal diagnostics, such as E_ERROR, terminate the script. @@ -279,7 +280,7 @@ A custom function for this type of exception Diagnostics can be added, removed, have their severity altered or be - elevated to a Throwable error in between PHP versions. + elevated to a Throwable error in between PHP versions. diff --git a/reference/stomp/stompexception.xml b/reference/stomp/stompexception.xml index 8e679ea2da6a..b2fb456efbc3 100644 --- a/reference/stomp/stompexception.xml +++ b/reference/stomp/stompexception.xml @@ -11,7 +11,7 @@
&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 Exceptions for more information about Exceptions in PHP.
From 8033f7a38db18876c327197dd8c8f3b497aadb5e Mon Sep 17 00:00:00 2001 From: Louis-Arnaud Date: Tue, 29 Sep 2026 09:02:12 +0200 Subject: [PATCH 19/20] Use simpara for inline-only paragraphs touched by the refactor --- .../incompatible/error-handling.xml | 4 +- language/control-structures/finally.xml | 44 ++++----- language/control-structures/throw.xml | 18 ++-- language/control-structures/try-catch.xml | 42 ++++---- language/error-handling.xml | 96 +++++++++---------- language/oop5/basic.xml | 6 +- reference/dom/domexception.xml | 4 +- reference/pdo/connections.xml | 4 +- reference/pdo/error-handling.xml | 4 +- reference/pdo/pdoexception.xml | 8 +- 10 files changed, 115 insertions(+), 115 deletions(-) diff --git a/appendices/migration70/incompatible/error-handling.xml b/appendices/migration70/incompatible/error-handling.xml index 8da24cfb0ffa..f12285f9b6cf 100644 --- a/appendices/migration70/incompatible/error-handling.xml +++ b/appendices/migration70/incompatible/error-handling.xml @@ -17,12 +17,12 @@ Error exceptions).
- + 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/language/control-structures/finally.xml b/language/control-structures/finally.xml index 997643fc9ab6..c51145f897a1 100644 --- a/language/control-structures/finally.xml +++ b/language/control-structures/finally.xml @@ -3,7 +3,7 @@ <sect1 xml:id="control-structures.finally" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>finally - + A &finally; block may also 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, @@ -12,7 +12,7 @@ The only exceptions to this rule are when the script is terminated abruptly, such as by a call to exit or by a fatal error (for example when the maximum execution time is exceeded). - + <exceptionname>Throwable</exceptionname> error handling with a &finally; block @@ -54,13 +54,13 @@ Hello World - + 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 @@ -89,14 +89,14 @@ Outer finally 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; @@ -180,11 +180,11 @@ finally catch Interaction between a &finally; block and an exception thrown in a &try; block - + If both the &try; block and the &finally; block throw an exception, the exception thrown from the &finally; block is the one that is propagated, and the exception thrown from the &try; block will be used as its previous exception. - + Exception in try and in finally @@ -225,11 +225,11 @@ string(6) "Fourth" 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 <exceptionname>Exception</exceptionname> @@ -270,12 +270,12 @@ outer catch </screen> </example> - <para> + <simpara> It is possible to &yield; within a &finally; block but if a <exceptionname>Throwable</exceptionname> error occurs and is not &catch;ed within the &foreach; a <literal>Cannot yield from finally in a force-closed generator</literal> <exceptionname>Error</exceptionname> is thrown. - </para> + </simpara> <example> <title> Error when &yield;ing in &finally; block when an <exceptionname>Exception</exceptionname> @@ -329,10 +329,10 @@ Stack trace: <sect2> <title>Interaction between a &finally; block and a call to <function>exit</function> - + When exit is called within a &try; or a &catch; block all &finally; blocks are skipped. - + Interaction between &finally; block and <function>exit</function> called in &try; block @@ -400,10 +400,10 @@ quit - + 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 <function>exit</function> @@ -432,10 +432,10 @@ inner finally Edge case of calling <function>exit</function> in a &foreach; over a generator - + This one edge case behaviour is highly dependent on which version of PHP the code is executed. - + @@ -463,20 +463,20 @@ try { } ]]> - + Output of the above example prior to PHP 7.1.14, 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 7.2.2, and prior to PHP 8.0.0 - + 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. @@ -36,12 +36,12 @@ Stack trace: - + 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 @@ -91,13 +91,13 @@ Stack trace: - + 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. + 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 index 1d1b6d1a629c..7e81d9edd374 100644 --- a/language/control-structures/try-catch.xml +++ b/language/control-structures/try-catch.xml @@ -5,47 +5,47 @@ try - + A &try; block is a block which 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 @@ -70,12 +70,12 @@ Hello World - + 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 @@ -108,12 +108,12 @@ string(11) "MyException" - + 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 @@ -130,10 +130,10 @@ try { - + Throwables can be &throw;n (or re-thrown) within a &catch; block. If not, execution will continue after the &catch; block that was triggered. - + Nested Exception @@ -169,10 +169,10 @@ string(4) "foo!" - + Throwing an object withing a &catch; block will not be caught by an adjacent &catch; block. - + Sequential catch blocks @@ -204,15 +204,15 @@ Stack trace: - + 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. + Only permitted in PHP 8.0.0 and later. See also the Exception class - + 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. - + @@ -32,14 +32,14 @@ <exceptionname>Throwable</exceptionname> errors - + 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 @@ -47,66 +47,66 @@ 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 throws an Error, even if a subclass declares its own __clone() method, with the following message: Trying to clone an uncloneable object of class Exception. - + <literal>Global exception handler</literal> - + 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. Unlike a &catch; block, execution does not resume afterwards: the script terminates once the handler returns. - + 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 <exceptionname>Exception</exceptionname> @@ -215,27 +215,27 @@ A custom function for this type of 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, most diagnostic errors do not disrupt the normal flow of execution. Fatal diagnostics, such as E_ERROR, terminate the script. - - + + 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 @@ -244,19 +244,19 @@ A custom function for this type of exception 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 @@ -264,30 +264,30 @@ A custom function for this type of exception 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. @@ -297,12 +297,12 @@ A custom function for this type of exception 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 @@ -318,13 +318,13 @@ set_error_handler('exceptions_error_handler'); ]]> - + 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 05d1a256b90a..bdf64c7d676c 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 diff --git a/reference/dom/domexception.xml b/reference/dom/domexception.xml index 3a041f237752..e6488c45735a 100644 --- a/reference/dom/domexception.xml +++ b/reference/dom/domexception.xml @@ -25,9 +25,9 @@ FIXME: Remove me once you perform substitutions This class is aliased as Dom\Exception in the Dom namespace. - + See also . - + diff --git a/reference/pdo/connections.xml b/reference/pdo/connections.xml index ef5f05fc2106..3bfb98ae4661 100644 --- a/reference/pdo/connections.xml +++ b/reference/pdo/connections.xml @@ -44,7 +44,7 @@ try { - + Just like any other exception, PDOException could be caught either explicitly, via a &catch; statement, or implicitly via set_exception_handler. @@ -54,7 +54,7 @@ try { As such, the &php.ini; option display_errors should be set to 0 on a production server. - + Upon successful connection to the database, an instance of the PDO class diff --git a/reference/pdo/error-handling.xml b/reference/pdo/error-handling.xml index c94dfcd69acd..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 for more information about handling Exceptions in PHP. - +
diff --git a/reference/pdo/pdoexception.xml b/reference/pdo/pdoexception.xml index 40b25c5f4c87..1a3fefe4bb62 100644 --- a/reference/pdo/pdoexception.xml +++ b/reference/pdo/pdoexception.xml @@ -8,13 +8,13 @@
&reftitle.intro; - + Represents an error raised by PDO. You should not throw a PDOException from your own code. - - + + See also . - +
From da81e6b8347b21af462dd7e60115b6b191039851 Mon Sep 17 00:00:00 2001 From: Louis-Arnaud Date: Mon, 5 Oct 2026 10:09:57 +0200 Subject: [PATCH 20/20] Address review feedback on the error handling pages --- .../incompatible/error-handling.xml | 4 +-- language/control-structures/finally.xml | 10 +++--- language/control-structures/throw.xml | 9 ++--- language/control-structures/try-catch.xml | 34 ++++++++---------- language/error-handling.xml | 36 ++++++++++--------- 5 files changed, 45 insertions(+), 48 deletions(-) diff --git a/appendices/migration70/incompatible/error-handling.xml b/appendices/migration70/incompatible/error-handling.xml index f12285f9b6cf..5b9a2adc3345 100644 --- a/appendices/migration70/incompatible/error-handling.xml +++ b/appendices/migration70/incompatible/error-handling.xml @@ -18,8 +18,8 @@ - A more complete 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 can be found + on the Throwable errors page. This migration guide will merely enumerate the changes that affect backward compatibility. diff --git a/language/control-structures/finally.xml b/language/control-structures/finally.xml index c51145f897a1..f2146d26696b 100644 --- a/language/control-structures/finally.xml +++ b/language/control-structures/finally.xml @@ -7,9 +7,9 @@ A &finally; block may also 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. + or if a Throwable error is not caught or is rethrown. It will be executed prior to resuming the normal execution flow. - The only exceptions to this rule are when the script is terminated abruptly, + The only exception to this rule is when the script is terminated abruptly, such as by a call to exit or by a fatal error (for example when the maximum execution time is exceeded). @@ -272,7 +272,7 @@ outer catch It is possible to &yield; within a &finally; block but if a - Throwable error occurs and is not &catch;ed within + Throwable error occurs and is not caught within the &foreach; a Cannot yield from finally in a force-closed generator Error is thrown. @@ -376,7 +376,7 @@ catch - All &finally; block and skipped when <function>exit</function> is called + All &finally; blocks are skipped when <function>exit</function> is called When exit is called within a &finally; block, - all other outer &finally; blocks are skipped as per the above behaviour. + all other outer &finally; blocks are skipped. Skipping outer &finally; block by calling <function>exit</function> diff --git a/language/control-structures/throw.xml b/language/control-structures/throw.xml index d7afa758c2ae..9bd0b2f993a1 100644 --- a/language/control-structures/throw.xml +++ b/language/control-structures/throw.xml @@ -4,8 +4,8 @@ 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 + The &throw; keyword is an expression and may be used in any expression context. + It takes an instance of a Throwable object as an argument. @@ -38,7 +38,8 @@ Stack trace: 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 + is unwound until the object is caught by a &catch; block or the global scope + is reached. In the latter case, the program is terminated with a fatal error containing the stack trace indicating where the Throwable object has been thrown. @@ -97,7 +98,7 @@ Stack trace: Using throw as an expression - Only permitted in PHP 8.0.0 and later. + Only permitted as of PHP 8.0.0. - try-catch blocks + Try...Catch try - A &try; block is a block which delimits a segment of code which might &throw; - a Throwable error which one wants to possibly handle. + A &try; block delimits a segment of code which might &throw; + a Throwable error that needs handling. 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. + error. If none can be found, it will unwind the call stack until one is found or a global error handler is reached. @@ -31,20 +30,15 @@ A &catch; block defines how to respond to a thrown Throwable error. - A &catch; block defines one or more subclasses of Throwable + It specifies 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. + The first &catch; block + that matches the class of the thrown Throwable + object will handle the error. + Normal execution resumes after the &catch; block without entering any other matching &catch; blocks. Catching an Exception @@ -79,7 +73,7 @@ Hello World Catching a union of classes to handle - testing(); &example.outputs; - @@ -132,7 +126,7 @@ try { Throwables can be &throw;n (or re-thrown) within a &catch; block. - If not, execution will continue after the &catch; block that was triggered. + If nothing is thrown, the execution resumes as normal. Nested Exception @@ -170,7 +164,7 @@ string(4) "foo!" - Throwing an object withing a &catch; block will not + Throwing an object inside a &catch; block will not be caught by an adjacent &catch; block. @@ -212,7 +206,7 @@ Stack trace: Omitting the caught variable - Only permitted in PHP 8.0.0 and later. + Only permitted as of PHP 8.0.0. 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. + until it is caught by a &catch; block or the global scope is reached, in which + case the program is terminated with a fatal error. All &finally; blocks it encounters along the way will be executed. @@ -53,8 +54,8 @@ The Standard PHP Library (SPL) provides various built-in exceptions. And it's possible to create custom exceptions by - extending - Exception. + extending the + Exception class. @@ -82,11 +83,11 @@ <literal>Global exception handler</literal> - 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. - Unlike a &catch; block, execution does not resume afterwards: the script + 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, + except that execution does not resume afterwards: the script terminates once the handler returns. @@ -94,7 +95,7 @@ Extending Exceptions - A User defined exception can be defined by extending the built-in + 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. @@ -201,15 +202,16 @@ A custom function for this type of exception Exception - - - ... - - + + + The Exception class has many subclasses, + among them the SPL exceptions and + those defined by extensions. + @@ -290,11 +292,11 @@ A custom function for this type of exception 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. + which is set using set_error_handler. Some diagnostics, such as E_ERROR and E_PARSE, cannot be handled this way (see - set_error_handler for the full list), but the others - can then be handled in various ways. For example, this can be used to show a custom + set_error_handler for the full list). + The others can 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.