Como posso obter mensagens de erro úteis em PHP?
Freqüentemente, tento executar um script PHP e obter uma tela em branco de volta. Nenhuma mensagem de erro; apenas uma tela vazia. A causa pode ter sido um erro de sintaxe simples (colchete incorreto, ponto-e-vírgula ausente) ou uma chamada de função com falha ou algo totalmente diferente.
É muito difícil descobrir o que deu errado. Eu acabo comentando o código, inserindo instruções "echo" em todos os lugares, etc. tentando restringir o problema. Mas certamente deve haver uma maneira melhor, certo?
Existe uma maneira de fazer o PHP produzir uma mensagem de erro útil, como o Java faz?
Respostas
Para erros de sintaxe, você precisa habilitar a exibição de erros no php.ini. Por padrão, eles estão desligados porque você não quer que um "cliente" veja as mensagens de erro. Verifique esta página na documentação do PHP para informações sobre as 2 diretivas: error_reporting
e display_errors
. display_errors
é provavelmente o que você deseja alterar. Se você não pode modificar o php.ini, você também pode adicionar as seguintes linhas a um arquivo .htaccess:
php_flag display_errors on
php_value error_reporting 2039
Você pode querer considerar o uso do valor de E_ALL (como mencionado por Gumbo) para sua versão do PHP para error_reporting
obter todos os erros. mais informações
3 outros itens: (1) Você pode verificar o arquivo de registro de erros, pois terá todos os erros (a menos que o registro tenha sido desativado). (2) Adicionar as 2 linhas a seguir o ajudará a depurar erros que não são erros de sintaxe:
error_reporting(-1);
ini_set('display_errors', 'On');
(3) Outra opção é usar um editor que verifica se há erros durante a digitação, como o PhpEd . PhpEd também vem com um depurador que pode fornecer informações mais detalhadas. (O depurador PhpEd é muito semelhante ao xdebug e se integra diretamente ao editor, de modo que você usa 1 programa para fazer tudo.)
O link do Cartman também é muito bom:http://www.ibm.com/developerworks/library/os-debug/
O seguinte ativa todos os erros:
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(-1);
Veja também os seguintes links
- http://php.net/manual/en/errorfunc.configuration.php#ini.display-errors
- http://php.net/manual/en/errorfunc.configuration.php#ini.display-startup-errors
- http://php.net/manual/en/function.error-reporting.php
O código a seguir deve exibir todos os erros:
<?php
// ----------------------------------------------------------------------------------------------------
// - Display Errors
// ----------------------------------------------------------------------------------------------------
ini_set('display_errors', 'On');
ini_set('html_errors', 0);
// ----------------------------------------------------------------------------------------------------
// - Error Reporting
// ----------------------------------------------------------------------------------------------------
error_reporting(-1);
// ----------------------------------------------------------------------------------------------------
// - Shutdown Handler
// ----------------------------------------------------------------------------------------------------
function ShutdownHandler()
{
if(@is_array($error = @error_get_last())) { return(@call_user_func_array('ErrorHandler', $error));
};
return(TRUE);
};
register_shutdown_function('ShutdownHandler');
// ----------------------------------------------------------------------------------------------------
// - Error Handler
// ----------------------------------------------------------------------------------------------------
function ErrorHandler($type, $message, $file, $line)
{
$_ERRORS = Array( 0x0001 => 'E_ERROR', 0x0002 => 'E_WARNING', 0x0004 => 'E_PARSE', 0x0008 => 'E_NOTICE', 0x0010 => 'E_CORE_ERROR', 0x0020 => 'E_CORE_WARNING', 0x0040 => 'E_COMPILE_ERROR', 0x0080 => 'E_COMPILE_WARNING', 0x0100 => 'E_USER_ERROR', 0x0200 => 'E_USER_WARNING', 0x0400 => 'E_USER_NOTICE', 0x0800 => 'E_STRICT', 0x1000 => 'E_RECOVERABLE_ERROR', 0x2000 => 'E_DEPRECATED', 0x4000 => 'E_USER_DEPRECATED' ); if(!@is_string($name = @array_search($type, @array_flip($_ERRORS))))
{
$name = 'E_UNKNOWN'; }; return(print(@sprintf("%s Error in file \xBB%s\xAB at line %d: %s\n", $name, @basename($file), $line, $message))); }; $old_error_handler = set_error_handler("ErrorHandler");
// other php code
?>
A única maneira de gerar uma página em branco com este código é quando você tem um erro no manipulador de desligamento. Copiei e colei do meu próprio cms sem testá-lo, mas tenho certeza de que funciona.
Você pode incluir as seguintes linhas no arquivo que deseja depurar:
error_reporting(E_ALL);
ini_set('display_errors', '1');
Isso substitui as configurações padrão no php.ini, que apenas fazem o PHP relatar os erros no log.
Erros e avisos geralmente aparecem nas configurações do php.ini ....\logs\php_error.log
ou ....\logs\apache_error.log
dependendo delas.
Erros úteis também são freqüentemente direcionados ao navegador, mas como não são html válidos, não são exibidos.
Portanto, "tail -f
"seus arquivos de log e quando você receber uma tela em branco, use IEs" ver "-> opções de menu" fonte "para ver a saída bruta.
Configuração PHP
2 entradas em php.ini determinam a saída de erros:
- display_errors
- error_reporting
Na produção , display_errors
geralmente é definido como Off
(o que é bom, porque a exibição de erros em sites de produção geralmente não é desejável!).
No entanto, no desenvolvimento , deve ser definido como On
, para que os erros sejam exibidos. Verifique !
error_reporting
(a partir do PHP 5.3) é definido por padrão para E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
(ou seja, tudo é mostrado exceto para avisos, padrões estritos e avisos de depreciação). Em caso de dúvida, defina-o E_ALL
para exibir todos os erros. Verifique !
Whoa whoa! Sem cheque! Não consigo mudar meu php.ini!
Isso é uma vergonha. Normalmente hosts compartilhados não permitem a alteração de seu arquivo php.ini e, portanto, essa opção infelizmente não está disponível. Mas não tema! Temos outras opções !
Configuração de tempo de execução
No script desejado, podemos alterar as entradas do php.ini em tempo de execução! Ou seja, ele será executado quando o script for executado! Doce!
error_reporting(E_ALL);
ini_set("display_errors", "On");
Essas duas linhas terão o mesmo efeito que alterar as entradas do php.ini como acima! Impressionante!
Ainda recebo uma página em branco / erro 500!
Isso significa que o script nem foi executado! Isso geralmente acontece quando você tem um erro de sintaxe!
Com erros de sintaxe, o script nem chega ao tempo de execução. Ele falha em tempo de compilação , o que significa que usará os valores do php.ini, que se você não alterou, pode não permitir a exibição de erros.
Logs de erros
Além disso, o PHP, por padrão, registra erros. Na hospedagem compartilhada, ele pode estar em uma pasta dedicada ou na mesma pasta do script ofensivo.
Se você tiver acesso a php.ini, poderá encontrá-lo na error_logentrada.
Estou sempre usando essa sintaxe no início do script php.
ini_set('error_reporting', E_ALL);
ini_set('display_errors', 'On'); //On or Off
Existe uma extensão realmente útil chamada " xdebug " que tornará seus relatórios muito mais agradáveis também.
Para solução de problemas rápida e prática, normalmente sugiro aqui no SO:
error_reporting(~0); ini_set('display_errors', 1);
para ser colocado no início do roteiro que está sob resolução de problemas. Isso não é perfeito, a variante perfeita é que você também habilite isso no php.ini
e que registre os erros no PHP para detectar erros de sintaxe e de inicialização.
As configurações descritas aqui exibem todos os erros, avisos e avisos, incluindo os estritos, independentemente da versão do PHP.
Próximas coisas a considerar:
- Instale o Xdebug e habilite a depuração remota com seu IDE.
Veja também:
- Relatório de erros (PHP da maneira certa.)
- Documentos de Constantes Predefinidas
- error_reporting()Docs
- display_errorsDocs
É possível registrar um gancho para tornar visível o último erro ou aviso.
function shutdown(){
var_dump(error_get_last());
}
register_shutdown_function('shutdown');
adicionar este código ao início de seu index.php o ajudará a depurar os problemas.
Se você for muito legal, pode tentar:
$test_server = $_SERVER['SERVER_NAME'] == "127.0.0.1" || $_SERVER['SERVER_NAME'] == "localhost" || substr($_SERVER['SERVER_NAME'],0,3) == "192";
ini_set('display_errors',$test_server);
error_reporting(E_ALL|E_STRICT);
Isso só exibirá erros quando você estiver executando localmente. Ele também fornece a variável test_server para usar em outros lugares quando apropriado.
Quaisquer erros que acontecerem antes da execução do script não serão detectados, mas para 99% dos erros que eu cometo, isso não é um problema.
No topo da página, escolha um parâmetro
error_reporting(E_ERROR | E_WARNING | E_PARSE);
Este é um problema de configuração carregada vs. tempo de execução
É importante reconhecer que um erro de sintaxe ou erro de análise ocorre durante a etapa de compilação ou análise , o que significa que o PHP irá parar antes mesmo de ter a chance de executar qualquer um de seu código. Portanto, se você estiver modificando a display_errors
configuração do PHP durante o tempo de execução (isso inclui qualquer coisa, desde usar ini_set
em seu código até usar .htaccess, que é um arquivo de configuração de tempo de execução), apenas as configurações padrão carregadas estão em jogo.
Como sempre evitar WSOD no desenvolvimento
Para evitar um WSOD você quiser ter certeza de que o seu arquivo de configuração carregado tem display_errors
ligado e error_reporting
pronto para -1
( esta é a E_ALL equivalente porque garante que todos os bits são ligados independentemente de qual versão do PHP você está executando ). Não codifique o valor constante de E_ALL, porque esse valor está sujeito a alterações entre as diferentes versões do PHP.
A configuração carregada é seu php.ini
arquivo carregado ou seu arquivo apache.conf
ou httpd.conf
ou virtualhost. Esses arquivos são lidos apenas uma vez durante o estágio de inicialização (quando você inicia o apache httpd ou php-fpm, por exemplo) e apenas substituídos por mudanças na configuração do tempo de execução. Certificar-se de que display_errors = 1
e error_reporting = -1
em seu arquivo de configuração carregado garante que você nunca verá um WSOD, independentemente da sintaxe ou erro de análise que ocorre antes de uma mudança de tempo de execução como ini_set('display_errors', 1);
ou error_reporting(E_ALL);
pode ocorrer.
Como encontrar seus arquivos de configuração carregados (php.ini)
Para localizar seu (s) arquivo (s) de configuração carregado (s), basta criar um novo arquivo PHP com apenas o seguinte código ...
<?php
phpinfo();
Em seguida, aponte seu navegador para lá e veja o Arquivo de configuração carregado e os arquivos .ini adicionais analisados , que geralmente estão na parte superior do seu phpinfo()
e incluirão o caminho absoluto para todos os arquivos de configuração carregados.
Se você (none)
vir em vez do arquivo, significa que não há um php.ini no caminho do arquivo de configuração (php.ini) . Portanto, você pode baixar o arquivo php.ini empacotado com o PHP aqui e copiá-lo para o caminho do arquivo de configuração como php.ini e, em seguida, certifique-se de que seu usuário php tenha permissões suficientes para ler esse arquivo. Você precisará reiniciar o httpd ou php-fpm para carregá-lo. Lembre-se, este é o arquivo de desenvolvimento php.ini que vem junto com o código-fonte do PHP. Portanto, não o use na produção!
Só não faça isso na produção
Esta é realmente a melhor maneira de evitar um WSOD em desenvolvimento. Qualquer um sugerindo que você coloque ini_set('display_errors', 1);
ou error_reporting(E_ALL);
no topo de seu script PHP ou usando .htaccess como você fez aqui, não vai ajudá-lo a evitar um WSOD quando ocorrer um erro de sintaxe ou de análise (como no seu caso aqui) se seu arquivo de configuração carregado foi display_errors
desligado.
Muitas pessoas (e instalações de estoque do PHP) usarão um arquivo ini de produção que foi display_errors
desativado por padrão, o que normalmente resulta na mesma frustração que você experimentou aqui. Porque o PHP já o desligou ao inicializar, então encontra uma sintaxe ou erro de análise e falha sem nada para gerar. Você espera que você ini_set('display_errors',1);
esteja no topo do seu script PHP deve ter evitado isso, mas não importa se o PHP não pode analisar o seu código porque ele nunca terá atingido o tempo de execução.
Para persistir e torná-lo confortável, você pode editar seu arquivo php.ini. Geralmente é armazenado em /etc/php.ini
ou /etc/php/php.ini
, mas mais locais php.ini
podem substituí-lo, dependendo das diretrizes de configuração do seu provedor de hospedagem. Verifique um phpinfo()
arquivo Loaded Configuration File
no topo, para ter certeza de qual foi carregado por último.
Pesquise display_errors nesse arquivo. Deve haver apenas 3 instâncias, das quais 2 são comentadas.
Altere a linha não comentada para:
display_errors = stdout
Não sei se vai ajudar, mas aqui está um pedaço do meu arquivo de configuração padrão para projetos php. Eu tendo a não depender muito das configurações do apache, mesmo no meu próprio servidor.
Nunca tive o problema do erro de desaparecimento, então talvez algo aqui lhe dê uma ideia.
Editado para mostrar APPLICATON_LIVE
/*
APPLICATION_LIVE will be used in process to tell if we are in a development or production environment. It's generally set as early as possible (often the first code to run), before any config, url routing, etc.
*/
if ( preg_match( "%^(www.)?livedomain.com$%", $_SERVER["HTTP_HOST"]) ) {
define('APPLICATION_LIVE', true);
} elseif ( preg_match( "%^(www.)?devdomain.net$%", $_SERVER["HTTP_HOST"]) ) {
define('APPLICATION_LIVE', false);
} else {
die("INVALID HOST REQUEST (".$_SERVER["HTTP_HOST"].")");
// Log or take other appropriate action.
}
/*
--------------------------------------------------------------------
DEFAULT ERROR HANDLING
--------------------------------------------------------------------
Default error logging. Some of these may be changed later based on APPLICATION_LIVE.
*/
error_reporting(E_ALL & ~E_STRICT);
ini_set ( "display_errors", "0");
ini_set ( "display_startup_errors", "0");
ini_set ( "log_errors", 1);
ini_set ( "log_errors_max_len", 0);
ini_set ( "error_log", APPLICATION_ROOT."logs/php_error_log.txt");
ini_set ( "display_errors", "0");
ini_set ( "display_startup_errors", "0");
if ( ! APPLICATION_LIVE ) {
// A few changes to error handling for development.
// We will want errors to be visible during development.
ini_set ( "display_errors", "1");
ini_set ( "display_startup_errors", "1");
ini_set ( "html_errors", "1");
ini_set ( "docref_root", "http://www.php.net/");
ini_set ( "error_prepend_string", "<div style='color:red; font-family:verdana; border:1px solid red; padding:5px;'>");
ini_set ( "error_append_string", "</div>");
}
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);
ini_set('html_errors', 1);
Além disso, você pode obter informações mais detalhadas com xdebug .
Eu recomendo Nette Tracy para melhor visualização de erros e exceções em PHP:
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
error_reporting(E_ALL | E_STRICT);
E ative os erros de exibição no php.ini
Você pode registrar seu próprio manipulador de erros em PHP. Despejar todos os erros em um arquivo pode ajudá-lo nesses casos obscuros, por exemplo. Observe que sua função será chamada, não importa como seu error_reporting atual esteja definido. Exemplo muito básico:
function dump_error_to_file($errno, $errstr) {
file_put_contents('/tmp/php-errors', date('Y-m-d H:i:s - ') . $errstr, FILE_APPEND);
}
set_error_handler('dump_error_to_file');
As duas linhas principais de que você precisa para obter erros úteis do PHP são:
ini_set('display_errors',1);
error_reporting(E_ALL);
Conforme apontado por outros contribuidores, eles estão desativados por padrão por motivos de segurança. Como uma dica útil - quando você estiver configurando seu site, é útil fazer uma mudança para seus diferentes ambientes para que esses erros estejam ATIVADOS por padrão em seus ambientes locais e de desenvolvimento. Isso pode ser feito com o seguinte código (de preferência em seu arquivo index.php ou config, de modo que esteja ativo desde o início):
switch($_SERVER['SERVER_NAME'])
{
// local
case 'yourdomain.dev':
// dev
case 'dev.yourdomain.com':
ini_set('display_errors',1);
error_reporting(E_ALL);
break;
//live
case 'yourdomain.com':
//...
break;
}
O FirePHP também pode ser útil.
abra seu php.ini, certifique-se de que está configurado para:
display_errors = On
reinicie seu servidor.
Você também pode tentar o PHPStorm como seu editor de código. Ele encontrará muitos erros de PHP e outros erros de sintaxe enquanto você digita no editor.
se você for um usuário ubuntu, vá para o seu terminal e execute este comando
sudo tail -50f /var/log/apache2/error.log
onde exibirá os 50 erros recentes. Há um arquivo de erro error.log
para apache2 que registra todos os erros.
Para ativar o relatório de erros completo, adicione ao seu script:
error_reporting(E_ALL);
Isso faz com que até mesmo avisos mínimos apareçam. E, apenas no caso:
ini_set('display_errors', '1');
Forçará a exibição de erros. Isso deve ser desativado em servidores de produção, mas não durante o desenvolvimento.
Os “ERRORS” são as coisas mais úteis para os desenvolvedores conhecerem seus erros e os resolverem para que o sistema funcione perfeitamente.
O PHP fornece algumas das melhores maneiras de conhecer os desenvolvedores por que e onde seu código está obtendo os erros, portanto, conhecendo esses erros, os desenvolvedores podem tornar seu código melhor de várias maneiras.
Melhores maneiras de escrever as duas linhas seguintes na parte superior do script para obter todas as mensagens de erro:
error_reporting(E_ALL);
ini_set("display_errors", 1);
Outra maneira de usar ferramentas de depuração como xdebug em seu IDE.
Você pode habilitar relatórios de erros completos (incluindo avisos e mensagens estritas). Algumas pessoas acham isso muito prolixo, mas vale a pena tentar. Defina error_reporting
como E_ALL | E_STRICT
em seu php.ini.
error_reporting = E_ALL | E_STRICT
E_STRICT
irá notificá-lo sobre funções obsoletas e dar-lhe recomendações sobre os melhores métodos para realizar certas tarefas.
Se você não quiser avisos, mas achar outros tipos de mensagens úteis, tente excluir os avisos:
error_reporting = (E_ALL | E_STRICT) & ~E_NOTICE
Certifique-se também de que display_errors
está habilitado no php.ini. Se sua versão do PHP for anterior a 5.2.4, defina-a como On
:
display_errors = "On"
Se sua versão for 5.2.4 ou mais recente, use:
display_errors = "stderr"
Além de error_reporting e a configuração display_errors ini, você pode obter erros SYNTAX dos arquivos de log do seu servidor web. Quando estou desenvolvendo PHP, carrego os logs do servidor web do meu sistema de desenvolvimento em meu editor. Sempre que testo uma página e obtenho uma tela em branco, o arquivo de log fica obsoleto e meu editor pergunta se desejo recarregá-lo. Quando o faço, pulo para o fundo e ocorre o erro de sintaxe. Por exemplo:
[Sun Apr 19 19:09:11 2009] [error] [client 127.0.0.1] PHP Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING in D:\\webroot\\test\\test.php on line 9
Para quem usa nginx e tem tela branca até para arquivo <?php echo 123;
. No meu caso, não tinha essa opção necessária para PHP no arquivo de configuração nginx:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
Esta opção não estava no arquivo fastcgi_params, então o PHP não funcionou e não houve erros nos logs.