Error and exception handling in php



Exceptions

Table of Contents

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.

catch

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.

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 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.

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 .

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.

Example #1 Converting error reporting to exceptions

function exceptions_error_handler ( $severity , $message , $filename , $lineno ) <
throw new ErrorException ( $message , 0 , $severity , $filename , $lineno );
>

Examples

Example #2 Throwing an Exception

function inverse ( $x ) <
if (! $x ) <
throw new Exception ( ‘Division by zero.’ );
>
return 1 / $x ;
>

try <
echo inverse ( 5 ) . «\n» ;
echo inverse ( 0 ) . «\n» ;
> catch ( Exception $e ) <
echo ‘Caught exception: ‘ , $e -> getMessage (), «\n» ;
>

// Continue execution
echo «Hello World\n» ;
?>

The above example will output:

Example #3 Exception handling with a finally block

function inverse ( $x ) <
if (! $x ) <
throw new Exception ( ‘Division by zero.’ );
>
return 1 / $x ;
>

try <
echo inverse ( 5 ) . «\n» ;
> catch ( Exception $e ) <
echo ‘Caught exception: ‘ , $e -> getMessage (), «\n» ;
> finally <
echo «First finally.\n» ;
>

try <
echo inverse ( 0 ) . «\n» ;
> catch ( Exception $e ) <
echo ‘Caught exception: ‘ , $e -> getMessage (), «\n» ;
> finally <
echo «Second finally.\n» ;
>

// Continue execution
echo «Hello World\n» ;
?>

Читайте также:  Error 001 awaiting installer action

The above example will output:

Example #4 Interaction between the finally block and return

function test () <
try <
throw new Exception ( ‘foo’ );
> catch ( Exception $e ) <
return ‘catch’ ;
> finally <
return ‘finally’ ;
>
>

The above example will output:

Example #5 Nested Exception

class Test <
public function testing () <
try <
try <
throw new MyException ( ‘foo!’ );
> catch ( MyException $e ) <
// rethrow it
throw $e ;
>
> catch ( Exception $e ) <
var_dump ( $e -> getMessage ());
>
>
>

$foo = new Test ;
$foo -> testing ();

The above example will output:

Example #6 Multi catch exception handling

class MyOtherException extends Exception

class Test <
public function testing () <
try <
throw new MyException ();
> catch ( MyException | MyOtherException $e ) <
var_dump ( get_class ( $e ));
>
>
>

$foo = new Test ;
$foo -> testing ();

The above example will output:

Example #7 Omitting the caught variable

Only permitted in PHP 8.0.0 and later.

class SpecificException extends Exception <>

function test () <
throw new SpecificException ( ‘Oopsie’ );
>

try <
test ();
> catch ( SpecificException ) <
print «A SpecificException was thrown, but we don’t care about the details.» ;
>
?>

Example #8 Throw as an expression

Only permitted in PHP 8.0.0 and later.

class SpecificException extends Exception <>

function test () <
do_something_risky () or throw new Exception ( ‘It did not work’ );
>

try <
test ();
> catch ( Exception $e ) <
print $e -> getMessage ();
>
?>

User Contributed Notes 13 notes

If you intend on creating a lot of custom exceptions, you may find this code useful. I’ve created an interface and an abstract exception class that ensures that all parts of the built-in Exception class are preserved in child classes. It also properly pushes all information back to the parent constructor ensuring that nothing is lost. This allows you to quickly create new exceptions on the fly. It also overrides the default __toString method with a more thorough one.

interface IException
<
/* Protected methods inherited from Exception class */
public function getMessage (); // Exception message
public function getCode (); // User-defined Exception code
public function getFile (); // Source filename
public function getLine (); // Source line
public function getTrace (); // An array of the backtrace()
public function getTraceAsString (); // Formated string of trace

/* Overrideable methods inherited from Exception class */
public function __toString (); // formated string for display
public function __construct ( $message = null , $code = 0 );
>

abstract class CustomException extends Exception implements IException
<
protected $message = ‘Unknown exception’ ; // Exception message
private $string ; // Unknown
protected $code = 0 ; // User-defined exception code
protected $file ; // Source filename of exception
protected $line ; // Source line of exception
private $trace ; // Unknown

public function __construct ( $message = null , $code = 0 )
<
if (! $message ) <
throw new $this ( ‘Unknown ‘ . get_class ( $this ));
>
parent :: __construct ( $message , $code );
>

public function __toString ()
<
return get_class ( $this ) . » ‘ < $this ->message > ‘ in < $this ->file > ( < $this ->line > )\n»
. » < $this ->getTraceAsString ()> » ;
>
>
?>

Now you can create new exceptions in one line:

class TestException extends CustomException <>
?>

Here’s a test that shows that all information is properly preserved throughout the backtrace.

function exceptionTest ()
<
try <
throw new TestException ();
>
catch ( TestException $e ) <
echo «Caught TestException (‘ < $e ->getMessage ()> ‘)\n < $e >\n» ;
>
catch ( Exception $e ) <
echo «Caught Exception (‘ < $e ->getMessage ()> ‘)\n < $e >\n» ;
>
>

echo » ;
?>

Here’s a sample output:

Источник

Good Practices: handling error and exceptions in PHP

About this series:


In this series, we are exploring what are the best practices a web developer must take care of when creating or managing PHP code.
Sanitize, validate and escape
Security and managing passwords
Handling error and exceptions

Introduction


21st October 1879 19:15:13

Menlo Park, New Jersey


A strong breeze is cooling down the evening,
​ ​
the weather has not been kind lately and the rain has been fallen continuously for the past 2 weeks and it does not seem it wants to stop anytime soon.
​​
inside a factory, several men are working like hell on something that has the potential to change the world as they know it.
​​

​​
The final test will happen in a few minutes and it will be the result of weeks of research, hard work and calculation.
​​
3
​​
2

1
​​
POP!!
​​
A flashlight up the room for a second then dark again, another day has passed, another failed one, another error.
​​
That’s the 9’999th now.
​​

“I have not failed. I’ve just found 10,000 ways that won’t work.”
Thomas Edison

​​
If you have ever heard motivational speaker like Brian Tracy, Tony Robin, Zig Ziglar or Jim Rohn you know that all of them have a problem with the way schools run around the world.
​​
In university and colleges, errors are punished rather than welcomed,
​​
In the real world though, errors are the only way you can become a better one.
​​
This is especially true in web development.

Trial and errors are definitely the best way to become great and to craft your skill.

It is also true that we need to be careful and pay attention to the error we make.

The reason for making errors is that we can manage and learn from them.

PHP make it easy to handle, manage and learn by error that can occur in your code.

Читайте также:  Rcpt error sending message to

How to manage errors in PHP 7

If you ask me what are the features that have improved the most between PHP 5.6 and PHP 7 or PHP 7.1 I will surely put error handling in the top 3 positions.
​​
The seventh version of our beloved programming language brought to us an interface with a defined goal:
​​
it needed to be easily implemented and be useful in lots of cases.
​​
The throwable interface,
​​
in fact, can be implemented by both types of class (Error class and Exception) and supply and a handful of methods that we can use to better understand and analyze our error.

Here you can see the class and how can you use it:

In the snippet above are showed all the methods you can use to debug a PHP error in your script (with lots of type hinting)

and the actual code you can use to try a block of code and throw an error or an exception.

Errors, errors everywhere!


Whoever has dealt with error prior to PHP 5.6 know what type of pain it was and the headache he needed to deal with during the debugging phase.

Previously errors were produced within the engine and you could have handled it as long as they weren’t fatal errors.

You also needed to consider that errors and exception were two completely different things in your code and it added another layer of difficulty to the already complicated situation.

From PHP 7 onwards, fatal errors result in error exception being thrown and you can easily manage not fatal errors with bespoke methods

I can, for instance, run some code and only throw an error in case of a fatal occurs.


If this is the first time you handle errors or you see a try-catch this may seem confusing you may feel you want to step back a bit,

Don’t worry, in Php Basics you will find all you need to know to be ready to read this article.

Bear with me while I explain what is happening:

In our pseudocode we have to element a variable and a funtion, both of them have not been defined , thus are unser or inexistent.

PHP handle an unset variable differently that a undefined function,

the first one is just an invalid variable a notice error, web developes work long hour, it can happen often,

the second error instead is an actual fuction, with maybe some important logic in it.

That is why in PHP an undefined function is a serious problem, a fatal error.

Having these two lines of code within the try block permits the catch to instanciate an instance of the Error class (the variable $e).

$e implements the Throwable interface, which means it can use all the method you saw in the previous paragraph. Hence $e->getMessage();

Creating a bespoke error handler


There may be occasions in which some errors that are not instace of the Error class occur.

If these errors are not fatal PHP allows you, as a developer, to define bespoke function and handle them the way you prefer.

To do so you need to use the set_error_handle() function.

This function accept either a string with the name of the function you want to use or an array that contains an object and the name of the method you are invoking.

The fuction can stop the script,

if you do not want it to continue or return a value and continue when the code invoked the function in the first place.

Let’s have a look at a practical yet easy example below.

set_error_handle() cannot manage fatal error, which means that, in order to test it, we need to simulate a warning (a division by zero will do),

then we’ll define the content of the function and catch the error when it occurs.


Do not forget that you want to hide errors from the production environment when an error occurs it has to be visible only on local or a staging server.

In fact, showing an error in production can give a massive hint about the vulnerability of your website to a hacker or malicious users.

Читайте также:  You must have valid object selected render error

To do this you can edit 3 settings within your php.ini

  • display_errors if set to false it will suppress errors;
  • log_errors store errors into a log file;
  • error_reporting configures which type of errors trigger a report;

Error Handling Functions

PHP has several functions that can make handling errors and easy tasks in this section you will find a brief description for each of them.

  • debug_•backtrace() it accepts few parameters like options’ flag and a number that limits the results and generate a summary of how your script got where it is, it does it returning an array variable;
  • debug_•print_•backtrace() it works in a similar way as the previous one but instead of creating an array of trace it prints them in an inverted chronological order;
  • error_•get_•last() it returns an associative array that contains the info of the last error occurred in the script;
  • error_•clear_•last() reset the internal error log of PHP, if used before error_get_last() the latter will return null;
  • error_•log() it requires a mandatory message as a parameter and sends it to the defined error handling routines;
  • error_•reporting() This function requires either none or error constants as a parameter (you can find the complete list here https://www.php.net/manual/en/errorfunc.constants.php ) and set the level of accuracy the PHP application must have when handling errors;
  • set_•error_•handler() and set_•exception_•handler() set bespoke functions that handle errors and exception;
  • restore_•error_•handler() and restore_•exception_•handler() it is used after set_•error_•handler() and set_•exception_•handler() it aims to revert the handler to the previous error handler it could be the built-in or a user-defined function;
  • trigger_•error() this function triggers an error by accepting a message as a mandatory parameter and an error_type’s flag as a discretionary one;
  • user_•error() alias of trigger_•error();

What are exceptions


Exceptions are relatively new features of PHP, they have been implemented only in PHP 5 but they quickly became a core part of any object-oriented programming script.

Exceptions are states of the scripts the require special treatment because the script is not running as it is supposed to.

Both Errors and Exception are just classes that implement the Throwable interface.

Like any other class in the OOP world, the can be extended,

which allows to create error hierarchies and create tailor the way you handle exceptions.

Something to pay attention to and that can lead to errors and misunderstandings is that you cannot declare your own class and then decide to throw exceptions.

The only classes that can throw error are the ones that implement the Throwable class.

Let’s play a game, look at the code and answer the following question.


Which exception is thrown?

In the example below the exception thrown is the SubException, it inherits from MainException which extends Exception.

The block is evaluated from the first (the one on top) to the last and when the exception matches the name of the class given it is triggered.

This above can be considered the best practice because we narrow down the message we want to show and eventually.

In case none of our classes matches, we use the PHP class Exception for an overall check.

Catch multiple exceptions at once


Until now we have seen several tries with several catches.

Each block of code echo a message with different errors,

Think at the case we create a dozen of different exceptions,

should we add a dozen of catch blocks? And what if we want to handle several types of error in the same way?

To manage this situation PHP provided the pipe keyword “ | ”;

Here is an example of how to use it:

The finally keyword


I am sure you have already seen a switch-case conditional structure in the past,
​​
if not I got an entire article about conditional statements in PHP.
​​
One of the elements of the switch statement is that if none of the cases is evaluated eventually a “default“ block, if present, is going to run.
​​
The try a catch allows to do something similar to your code by providing the keyword finally


A common use for this keyword is, as shown in the example above, when we need to close a file that we have previously opened inside the try block.
​​
You must remember that the code inside the finally block is always executed, even if exceptions are thrown earlier in the script.
​​
But you are free to use it whenever you believe this will help your case.
​​

If you think this article was useful and you want to learn more about good practices in PHP click the image below

Источник

Оцените статью
toolgir.ru
Adblock
detector