📜 ⬆️ ⬇️

Handling critical errors in PHP

The article describes the functionality that is available in PHP (relevant for 5.3.x) for handling errors of all types, including code interpretation errors (E_ERROR, E_PARSE, E_WARNING, etc). This processing will help you to a managed page display in case of such problems. The article contains many descriptions and working examples (architectures) in order to immediately use it in its software product. In the end, well, the site was slightly broken, well, you must inform the search engine with the title 4xx or 5xx and entertain the user, instead of returning the white screen (or worse than the screen with sacred information, for hackers) with the answer 200 Ok.



The idea to write this topic arose when I asked 2 questions bravely:

From my karma and adding to favorites, I realized that they turned out to be interesting for PHP habrasoobschestva. For this reason, I decided to formalize the solutions to these questions in the form of an article, so that it would be easier and comprehensive for people and search engines to find the necessary information.
')
If you are interested, then the details under the cut ...


Reasons for using


The user / search engine is required to clearly answer that there is a problem on the server. Without the use of a specific feng shui, this is quite difficult to achieve, and sometimes impossible. Then I shed light on all this, well, I leave a note to myself, because a week ago I did not know what to undertake, and, probably, many newcomers will also be discouraged.

Function descriptions


This functionality is available in PHP to handle errors and control the output. Here is a description of their goodies and flaws. I will not give the documentation, I will only refer to its pages and describe my opinion. All that will be given is only a small fraction, I will cite references to the relevant sections of the documentation at the end of the article. So we meet:

- Control of non-critical errors: notes, warnings, user errors. In general, everything that does not complete the interpretation is abnormal.
set_error_handler - Sets a user-defined error handler.
Needed in order to write to the log all such errors. If you do not specify it, then this is not written to the log, but I always want to know under what combat situations remarks and warnings can be triggered. That is, it allows the user to automatically test the product and he will not even notice it.
If the function is not set, then PHP only tries to display data on the screen, and if it is not given to it, then there are no signs of life from these types of errors at all.

- Control, exceptions: is an error of type E_ERROR.
set_exception_handler - Sets a custom exception handler
Well, I do not know why it was invented at all, when there is what is described below and just handling an error of the type Exception. So I inform you that it simply exists. It intercepts the critical error "exception" and allows something to do with it. In any case, the script ends. Personally, her work by default is enough for me (writes to the logs, tries to display on the screen). I would not redefine it at all, otherwise I’ll have to write the exception log myself.

- Output control functions: Here I will describe 3 functions that should be known for various reasons. For example, for performance problems or for header output problems. In our case, it is required to display error headers.

ob_start - Enable output buffering
ob_flush - Reset (send) output buffer
ob_end_clean - Clears (erases) the output buffer and disables output buffering.

In short, these functions allow you to write all the data output via echo into a buffer. This functionality allows you to send headers in any part of the code, as well as many other things whose topics are not related to this article. And if suddenly there was trouble. You can then reset the entire buffer and the entire stack (this is not in this article), write the error header and display a notification to the user.

- Getting the last error that occurred: it should be used together with other interception functions that are described here.
error_get_last - Getting information about the last error that occurred
With it, it is possible to return the last error. It is very convenient for her to catch critical errors and the code becomes optimal (appeared with 5.2.x if that).

- The function that starts after everything has worked: Drum roll.
register_shutdown_function - Registers a function that will be executed upon completion of the script. Completion can be regular or emergency, without a difference.
Many pros and no cons:

Many Object Oriented People Will Be Delighted


That all the above functions can be registered even on methods of classes, and also, for sure, on static methods of classes in the same way. True, the method is not very obvious to the eyes of an ordinary non-PHP programmer.
The handler parameter is required to be specified via an array, with the elements “object class name |”, “object method”. The installed method must be public. An example for the set_error_handler function:
<?php class BaseErrorCatcher { public function __construct() { set_error_handler(array($this, 'ErrorCatcher')); echo ",  \n"; $errorVarArray['real index'] = true; echo $errorVarArray['error index']; } public function ErrorCatcher($errno, $errstr) { echo ",     -  : $errstr\n"; } } error_reporting(E_ALL | E_STRICT); //       ini_set('display_errors','On'); //         new BaseErrorCatcher(); //   ?> 

Result:
 friend i created
 friend, yes you probably screwed it up somewhere in this: Undefined index: error index


Working example


Example of work, class architecture for universal and complete error control. I investigated this question very thoroughly and composed a hybrid method, from the answers to the questions I asked .

Conditions

There is a file with a code that is launched first or before a code in which an error may appear and this file and all files before it are 100% debugged with the impossibility of an error. Here is a condition that would be easier - without errors until all the registrations of the above functions have passed. This file describes these methods of error control in the complex. The buffer is monitored; if an error occurs, then reset the buffer and output an error.

Code with comments

From myself I will add that the code did not test, since this is a simplified scheme of what I have in the code, comments are accepted
 <?php class ErrorSupervisor { public function __construct() { //   set_error_handler(array($this, 'OtherErrorCatcher')); //    register_shutdown_function(array($this, 'FatalErrorCatcher')); //    ob_start(); } public function OtherErrorCatcher($errno, $errstr) { //  : // -    return false; } public function FatalErrorCatcher() { $error = error_get_last(); if (isset($error)) if($error['type'] == E_ERROR || $error['type'] == E_PARSE || $error['type'] == E_COMPILE_ERROR || $error['type'] == E_CORE_ERROR) { ob_end_clean(); //  ,    //   : // -    // -   500 // -       } else { ob_end_flush(); //  ,    } else { ob_end_flush(); //  ,    } } } //   $errorController = new ErrorSupervisor(); //   //  ,      echo "  "; //   ( ,        ) include 'null'; //  OtherErrorCatcher // require 'null'; //  FatalErrorCatcher // require 'foobar.php'; //        ?> 


Links


Documentation sections



Other useful information



Thanks for attention.

UPD: According to the advice from the comments, I added the ErrorSupervisor class with new functionality, corrected a couple of misconceptions, added additional interesting information on the topic, slightly debugged the code

UPD2 Attention: A friend in PHP reason has written a good article about bit operations in PHP in time for the topic of this article, I advise you to read. This knowledge allows you to write code more elegantly. To change the text of this article is no longer in order that the meaning would be preserved.

Source: https://habr.com/ru/post/134499/


All Articles