Never use error_reporting(0);
, this affects more than display the errors, it affects the logs saved, which is not a good idea, just use the:
ini_set('display_errors', 0);
This will already prevent errors from being displayed to the user and the most it will get is the "500 Internal Error Server'
An ideal setting for the error_reporting
would be:
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED);
This will cause all errors to be saved on log (if it is authorised to do so log), except notifications, type errors Strict, usage errors and errors of discontinued functions, classes or functionalities.
More details on this reply: Why use error_reporting with display_errors and display_startup_errors?
For development I recommend enabling everything, after all it is development:
ini_set('display_errors', 1);
error_reporting(E_ALL|E_STRICT);
Note that in modern versions of PHP only E_ALL
is enough, the use of E_ALL|E_STRICT
was more for retro-compatibility.
In production in php.ini you can configure the logs error setting so:
error_log = /home/user/php/logs.txt
There is no problem in doing this in homologation and development environments, since there are pages that can be ordered via Ajax and you may not be able to notice the error when developing.
Note also that on some shared servers there is usually no way to change the error_log =
, but usually it is already enabled and using the echo ini_get('error_log');
(will not display to the user :)
) you can pick up the location where you were saved and maybe by SSH or SFTP download the log generated diary.
Another example of how to capture logs as I quoted in /a/34818/3635, would be using set_error_handler
combined with register_shutdown_function
, you could use this to send an error to an email, or something like that.
Anyway I would say that the ideal is to correct as many errors as possible and test the system well before sending it to production and if there is any error it was not possible to detect the log should inform only you.
How to display errors in a friendly way
... how I could not display the error message and yes create logs error, then redirect the user to the previous page, stating "Error occurred"?
Overall between display or not is the least of the problems in my view, the issue is the system fails and cause a number of side effects cascaded, for example generating invalid/incomplete records in the database, as said ideal is to handle everything possible, for example using mysql with innodb (myisam can’t stand it) you have the rollback:
if (!mysqli_query($link, 'INSERT ... xyz...')) {
die('Erro ao inserir xyz');
}
if (!mysqli_query($link, 'UPDATE... status...')) {
die('Erro ao atualizar status');
}
if (!mysqli_query($link, 'UPDATE... chat...')) {
die('Erro ao atualizar chat');
}
Assuming the last one query fail, but it’s important, you’d have updates on status and in Xyz that there shouldn’t be, because the system failed, now use:
/*Desativa o autocommit*/
mysqli_autocommit($link, false);
if (!mysqli_query($link, 'INSERT ... xyz...')) {
die('Erro ao inserir xyz');
}
if (!mysqli_query($link, 'UPDATE... status...')) {
mysqli_rollback($link); //Desfaz
die('Erro ao atualizar status');
}
if (!mysqli_query($link, 'UPDATE... chat...')) {
mysqli_rollback($link); //Desfaz
die('Erro ao atualizar chat');
}
mysqli_commit($link);
He’ll just do the commit if you’ve been through all ifs
, of course this is a very simple example, another situation is that people always take data from $_GET
and $_POST
without checking, simply doing this:
$nome = $_POST['nome'];
$email = $_POST['email'];
When they could do this (it’s just an example):
$nome = $_POST['nome'];
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if (!validaNome($nome)) { //Função "teórica"
die('Dados do formulário vazio');
}
if (!$email) {
die('Dados do formulário vazio');
}
These would be some examples, the die
is optional, in case I find it complicated to use it when it depends on the layout, you could group the errors and send them at the end, but this is a matter of experience and how your system was designed. Now about script errors that don’t have to do directly with "logic" or lost data, I mean FATAL and PARSE errors, as I said should be things that you should always check in the development, but of course I understand that this can happen back and forth, in case you could use the set_error_handler
and the register_shutdown_function
combined to display a fixed message at the top or to use ob_start
could generate an error page with nothing else (note that ob_start
can increase server consumption, which personally I don’t think is a good idea, I just cited it as an example, there are other ways to do this), for example:
create a global.php
<?php
ob_start(); //Inicia o buffer
function handleErrors($errno, $errstr, $errfile, $errline, $details = null) {
static $log; //Variavel static para detectar erros repetidos
if (isset($loggers) === false) {
$log = array();
}
$localizacao = $errfile . ':' . $errline;
if (in_array($localizacao, $log)) {
return true;
}
$localizacao[] = $localizacao; //Salva o erro para evitar ser eviado mais de de uma vez
$msg = 'Erro ' . $errstr .
' no arquivo: ' . $errfile .
' na linha: ' . $errline;
error_log($msg, 1, '[email protected]');
ob_end_clean(); //Limpa o buffer
require 'erroamigavel.php';
return true; //Não executa o "handler interno" do PHP
}
set_error_handler('handleErrors', E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED);
register_shutdown_function(function () {
$error = error_get_last();
$type = $error['type'];
if (!in_array($type, array(E_NOTICE, E_STRICT, E_DEPRECATED))) {
handleErrors($type, $error['message'], $error['file'], $error['line']);
);
}
});
Include this global.php in all files at the beginning like this:
<?php
require_once 'global.php';
Note that if the file you included has a PARSE error the global.php will probably not work
And then create a file called erroamigavel.php
with the content you want to display to the user, for example:
<!DOCTYPE html>
<html>
<head>
<title>Erro</title>
</head>
<body>
<h1>Ouve um erro na página</h1>
<p>Os administradores já foram notificados e estão trabalhando para corrigir</p>
</body>
</html>
note that it is all example, it is not something that will be copy and paste, I myself am not "fan" of ob_start()
for the reason I have already mentioned, only the use if necessary is even possible to do in other ways, but it depends a lot on how your system was created, in my framework personal for example I can do something like this without needing to ob_start()
.
In production it is best not to display any error messages or information about the system/technology/framework/platform etc to provide no detail to a possible attacker.
– rray
I don’t think you can show potentially dangerous information, but that doesn’t stop you from having well hidden and descriptive error logs :)
– Artur Trapp
@Guilhermebirth you ask about: Is it necessary to use ini_set('display_errors', 0);? Is error_reporting(0) not enough? while I wonder if: Since problems can be generated, with bank passwords, from other websites and so endlessly, disabling errors is the best alternative?
– UzumakiArtanis
You ask about functionality, while I ask about theory, it’s not the same duplicate question
– UzumakiArtanis
You marked the question as duplicate, so I went to see what was duplicated from the other question, and there you ask about: Is it necessary to use ini_set('display_errors', 0);? error_reporting(0); is that not enough? while I wonder if: Since problems can be generated, with bank passwords, from other websites and so endlessly, disabling errors is the best alternative?
– UzumakiArtanis
All right, thanks again
– UzumakiArtanis
I was just saying that I think the question doesn’t seem duplicated once you ask about ini_set functionality and error Reporting, while I ask about theory: "Since problems can be generated, with bank passwords, from other websites and so endlessly, disabling errors is the best alternative?" and later I made an Edit incrementing: the question "exactly how could I not display the error message but create error logs, then redirect the user to the previous page by stating "Error occurred"?" it doesn’t seem the same double question
– UzumakiArtanis
Maybe your other question might even look like a "related", but in my view, not as duplicate
– UzumakiArtanis
@Sauldasilvarolim see edition http://answall.com/a/195941/3635 I also reopened the question.
– Guilherme Nascimento
When the programmer is creating the system in Local server, it is necessary that the errors are enabled, so that the same can fix it, on the other hand, when we have a system already ready and hosted, it is the best option to hide all error messages, because if a malicious user catches this error, he can use it against the system itself, thus causing a huge headache.
– Félix
Related: How to present untreated exceptions?
– vinibrsl