Answer the question
In order to leave comments, you need to log in
PHP - How to return managed content on PHP critical error (E_ERROR, E_PARSE)?
Hello inquisitive minds.
In this question, I would like to continue the popular topic of questions about error handling in PHP.
Answer the question
In order to leave comments, you need to log in
register_shutdown_function(function () {
$error = error_get_last();
if ($error && ($error['type'] == E_ERROR || $error['type'] == E_PARSE || $error['type'] == E_COMPILE_ERROR)) {
if (strpos($error['message'], 'Allowed memory size') === 0) { // если кончилась память
ini_set('memory_limit', (intval(ini_get('memory_limit'))+64)."M"); // выделяем немножко что бы доработать корректно
Log::error("PHP Fatal: not enough memory in ".$error['file'].":".$error['line']);
} else {
Log::error("PHP Fatal: ".$error['message']." in ".$error['file'].":".$error['line']);
}
// ... завершаемая корректно ....
}
})
What immediately catches the eye: you need a 503 error instead of a 404.
I solved a similar problem using the standard output buffer interception (ob_start...). The trick is that the buffer handler is called even in case of fatal errors (specified by you), thus by checking in the buffer handler if an error has occurred, we can already send the necessary headers, etc.
ob_start('ob_end');
...
function ob_end($outputData)
{
$error = error_get_last();
if (is_array($error) && in_array($error['type'], array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR)))
{
/* Фатальная ошибка, отдаем 500 */
}
return $outputData;
}
Everything is fine, but somehow they forgot to remind everyone that error_get_last () is supported starting from 5.2.0
Crutches for earlier versions, these are just crutches.
200 is not always given
: stackoverflow.com/a/8295606
it seems impossible to make this work in conjunction with ErrorDocument
Colleagues.
First, I agree with what was said above. This is also correct. He himself did similar things, blocked errors, wrote to the log, sent to the mail, etc.
Secondly, if I was asked to make such a feature in a good solid project, then I would not reinvent the wheel, but use the solution out of the box.
Popular frameworks Symfony2, Yii - already support this out of the box, and for a long time.
I didn’t check the overflow from memory, it catches the rest without problems and returns the 500 error, that is, as it should (the amendment above, it is not necessary to give the 503rd. You can use any 5xx, this gesture will tell the search engine - “Oh, ask me later ...”, 404 - in this case, it is better not to give it back, it can affect the position of the site in the search - if this is important to you.).
The only limitation is to the style of the code, write without warings and notices, they are also caught. Otherwise, you run the risk of making a project that will only work in production mode, that is, with errors turned off. Debugging such things is not the most pleasant experience. In addition, the number of errors in such code is an order of magnitude higher.
Thirdly, the problem needs to be looked at more broadly.
The fact that the php code falls out when a syntax error or lack of memory occurs is mega bad. The solution is to override the error handling functions - Ihmo, a crutch, but sometimes you can’t do without it.
How to make such a crutch is described almost in the question itself. For myself, I understood the essence of the discussion as follows - and how you need to build the application logic (architecture - if you want), so that it is correct from the point of view of error handling.
The example with HTTP errors and statuses is not the only one. Other options are also possible.
Here's the idea. What and how to do depends on your project. This may not be a complex site that gives information, but it may be a rather complex complex in which business logic is embedded, it can work both when receiving pages and when performing background tasks (for example, scripts in CronTab).
In a nutshell, then I think like this:
- break the logic code into blocks (preferably independent, they can be hierarchical).
- run these blocks as if "in a sandbox" ( the question of how depends on the application itself, someone may not succeed, or for this you will have to change the structure of the database, some algorithms inside the application, etc.)
- on successful execution of the block, apply the result. Something broke, we notify the admin about a critical situation.
Critical situations are best caught with Unit tests, and if this is not possible, then with all types of testing.
Something like that.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question