Pergunta

Na sua opinião, é sempre válida para usar o operador @ para suprimir um erro / aviso em PHP enquanto que poderá ser lidar com o erro?

Se sim, em que circunstâncias você usaria isso?

Exemplos de código são bem-vindos.

Edit: Nota para repliers. Eu não estou olhando para transformar relatórios de erros fora, mas, por exemplo, a prática comum é usar

@fopen($file);

e verifique depois ... mas você pode se livrar do @ fazendo

if (file_exists($file))
{
    fopen($file);
}
else
{
    die('File not found');
}

ou similar.

Eu acho que a pergunta é - existe em qualquer lugar que @ tem que ser usado para suprimir um erro, que não pode ser tratado de qualquer outra maneira

?
Foi útil?

Solução

Eu suprimir o erro e manipulá-lo . Caso contrário, você pode ter um TOCTOU edição (Time-of-cheque, o tempo de uso. Por exemplo, um arquivo pode ficar excluído após file_exists retornos verdadeiros, mas antes fopen).

Mas eu gostaria de não apenas erros suprimir para fazê-los ir embora. Estes melhor que seja visível.

Outras dicas

Nota: Em primeiro lugar, eu percebo que 99% dos desenvolvedores PHP usar o operador de supressão de erro (eu costumava ser um deles), por isso estou esperando qualquer dev PHP que vê este discordar

.

Na sua opinião, é sempre válida para usar o operador @ para suprimir um erro / aviso em PHP enquanto que poderá ser lidar com o erro?

Resposta curta:
Não!

resposta mais longa mais correto:
Eu não sei como eu não sei tudo, mas até agora eu não encontrei uma situação em que era uma boa solução.

Por que é ruim:
Em que eu acho que é cerca de 7 anos usando PHP agora que eu vi agonia depuração interminável causado pelo operador de supressão de erro e nunca se deparar com uma situação em que era inevitável.

O problema é que o pedaço de código que você está suprimindo erros para, podem atualmente apenas provocar o erro que você está vendo; no entanto, quando você alterar o código que a linha suprimida depende, ou o ambiente em que ele é executado, então não há qualquer chance de que a linha vai tentar mostrar um erro completamente diferente do que você estava tentando ignorar. Então como você rastrear um erro que não é a saída? Bem-vindo ao depurar o inferno!

Levei muitos anos para perceber quanto tempo eu estava perdendo a cada dois meses por causa de erros suprimidas. Na maioria das vezes (mas não exclusivamente), este foi depois de instalar um terceiro script / app / biblioteca que estava livre de erros no ambiente de desenvolvedores, mas não a minha causa de um php ou configuração do servidor diferença ou dependência ausente que teria normalmente saída de um erro imediatamente alertando para qual era o problema, mas não quando o dev acrescenta a magia @.

As alternativas (dependendo da situação e resultado desejado):
Lidar com o erro real que você está ciente, de modo que se um pedaço de código vai causar um certo erro, então ele não é executado nessa situação particular. Mas eu acho que você começa esta parte e você estava apenas preocupado com os usuários finais vendo erros, que é o que eu quero agora endereço.

Para erros regulares você pode configurar um manipulador de erro para que eles saem da maneira que você desejar quando é que você visualizar a página, mas escondido de usuários finais e registrado para que você saiba quais os erros que seus usuários estão provocando.

Para erros fatais definir display_errors para fora (o manipulador de erro ainda é acionado) no seu php.ini e ativar o log de erro. Se você tem um servidor de desenvolvimento, bem como um servidor ativo (que eu recomendo), então este passo não é necessário em seu servidor de desenvolvimento, assim você ainda pode depurar esses erros fatais sem ter que recorrer a olhar para o arquivo de log de erro. Há até um truque usando a função de desligamento para enviar uma grande quantidade de erros fatais para o manipulador de erro.

Em resumo:
Por favor, evitá-lo. Pode haver uma boa razão para isso, mas ainda estou para ver um, então, até aquele dia é a minha opinião de que o (@) operador de supressão de erro é mau.

Você pode ler meu comentário sobre o erro Operadores de Controle página no manual do PHP, se quiser mais informações.

Sim supressão faz sentido.

Por exemplo, o comando fopen() retornos FALSE se o arquivo não pode ser aberto. Isso é bom, mas também produz uma mensagem de aviso PHP. Muitas vezes você não quer que o aviso - você vai verificar se há FALSE-se

.

Na verdade, a PHP Manual sugere especificamente usando @ neste caso!

Se você não quer uma advertência lançada quando utilizando funções como fopen (), você pode suprimir as exceções de erro, mas de uso:

try {
    if (($fp = @fopen($filename, "r")) == false) {
        throw new Exception;
    } else {
        do_file_stuff();
    }
} catch (Exception $e) {
    handle_exception();
}

Eu nunca me permitir usar '@' ... período.

Quando eu descobrir o uso de '@' no código, eu adicionar comentários para torná-lo flagrantemente aparente, tanto no ponto de uso, e no bloco de documentação em torno da função onde é usado. Eu também tenho sido mordido por "perseguir um fantasma" depuração devido a este tipo de supressão de erro, e espero torná-lo mais fácil para a pessoa seguinte, destacando seu uso quando eu encontrá-lo.

Nos casos em que eu estou querendo o meu próprio código para lançar uma exceção se uma função PHP nativa encontrar um erro, e '@' parece ser o caminho mais fácil para ir, eu optar para fazer outra coisa que recebe o mesmo resultar, mas é (mais uma vez) flagrantemente aparente no código:

$orig = error_reporting(); // capture original error level
error_reporting(0);        // suppress all errors
$result = native_func();   // native_func() is expected to return FALSE when it errors
error_reporting($orig);    // restore error reporting to its original level
if (false === $result) { throw new Exception('native_func() failed'); }

Isso é um código muito mais que simplesmente escrever:

$result = @native_func();

mas eu prefiro fazer a minha necessidade de supressão muito óbvio, por causa da pobre alma de depuração que me segue.

supressão de erro deve ser evitado a menos que você sei você pode lidar com todas as condições.

Isto pode ser muito mais difícil do que parece à primeira vista.

O que você realmente deve fazer é confiar em "error_log" do php para ser o seu método de comunicação, como você não pode confiar em usuários que visualizam páginas para relatar erros. (E você também deve desativar php de exibir esses erros)

Então, pelo menos você vai ter um relatório completo de todas as coisas erradas no sistema indo.

Se você realmente deve lidar com os erros, você pode criar um manipulador de erro personalizado

http://php.net/set-error-handler

Em seguida, você poderia enviar exceções (que podem ser manipuladas) e fazer qualquer coisa necessária para relatar erros estranhos à administração.

A maioria das pessoas não entendem o significado da mensagem de erro.
Sem brincadeiras. A maioria deles.

Eles pensam que as mensagens de erro são todos iguais, diz que "algo der errado!"
Eles não se preocupam em lê-lo.
Embora seja parte mais importante da mensagem de erro - e não apenas o fato de ter sido levantada, mas o seu significado. Pode dizer-lhe o está errado. Mensagens de erro são para ajudar, não para incomodá-lo com "como esconder isso?" problema. Esse é um dos maiores mal-entendidos no mundo do novato web-programação.

Assim, em vez de engasgos mensagem de erro, deve-se ler o que diz. Tem não somente um "arquivo não encontrado" valor. Não pode haver milhares erros diferentes: permission denied, save mode restriction, open_basedir restriction etc.etc. Cada um requer medidas adequadas. Mas se você amordaçá-lo você nunca vai saber o que aconteceu!

O OP é bagunçar erro Relatórios com o erro manipulação , embora seja muito grande diferença!
manipulação de erro é para o usuário. "Algo aconteceu" é suficiente aqui.
Enquanto o relatório de erros é para programador, que desesperadamente precisa saber o que certamente aconteceu.

Assim, nunca mais mordaça mensagens de erros. Ambos registrá-lo para o programador, e segurá-lo para o usuário.

não há uma maneira de suprimir das advertências php.ini e erros? Nesse caso, você pode depurar mudando apenas uma bandeira e não tentando descobrir qual @ está escondendo o problema.

Usando @ é por vezes contraproducente. Na minha experiência, você deve sempre recorrer erro relatando off no php.ini ou chamada

error_reporting(0);

em um site de produção. Dessa forma, quando você está em desenvolvimento você pode apenas comentar a linha e manter erros visíveis para depuração.

O único lugar onde eu realmente necessário para usá-lo é a função eval. O problema com eval é que, quando a corda não pode ser analisado devido a um erro de sintaxe, eval não retorna falso, mas gera um erro, como ter um erro de análise no script regular. A fim de verificar se o script armazenado no string é analisável você pode usar algo como:

$script_ok = @eval('return true; '.$script);

AFAIK, esta é a maneira mais elegante de fazer isso.

Um lugar que eu usá-lo é em código socket, por exemplo, se você tem um tempo limite definido você receberá um aviso sobre isso, se você não incluir @, mesmo que seja válida para não ficar um pacote.

$data_len = @socket_recvfrom( $sock, $buffer, 512, 0, $remote_host, $remote_port )

Você não quer tudo suprimir, uma vez que retarda o seu script.

E sim, há uma maneira tanto em php.ini e dentro do seu script para remover erros (mas só faça isso quando você está em um ambiente vivo e registrar seus erros do php)

<?php
    error_reporting(0);
?>

E você pode ler este para a versão php.ini de desligá-lo.

Se você estiver usando um erro personalizado função de manipulação e quero suprimir um erro (provavelmente um erro conhecido), use este método. O uso de '@' não é uma boa idéia neste contexto, uma vez que não vai erro Suprimir se manipulador de erro está definido.

Write 3 funções e chamada assim.

# supress error for this statement
supress_error_start();  
$mail_sent = mail($EmailTo, $Subject, $message,$headers);
supress_error_end(); #Don't forgot to call this to restore error.  

function supress_error_start(){
    set_error_handler('nothing');
    error_reporting(0);
}

function supress_error_end(){
    set_error_handler('my_err_handler');
    error_reporting('Set this to a value of your choice');
}

function nothing(){ #Empty function
}

function my_err_handler('arguments will come here'){
      //Your own error handling routines will come here
}

Hoje eu encontrei um problema que foi um bom exemplo de quando se pode querer usar pelo menos temporariamente o operador @.

É uma longa história feita curto, eu encontrei informações de logon (nome de usuário e senha em texto simples) escrito no traço de log de erro.

Aqui um pouco mais informação sobre esta questão.

A lógica logon está em uma classe de seu próprio, porque o sistema é suposto que oferecem diferentes mecanismos de logon. Devido a problemas de migração de servidor havia ocorrendo um erro. Esse erro despejado todo o trace no log de erro, incluindo informações senha! Um método esperava que o nome de usuário e senha como parâmetros, daí traço escreveu tudo fielmente no log de erro.

A correção a longo prazo aqui é refatorar disse classe, em vez de usar nome de usuário e senha como 2 parâmetros, por exemplo, usando um único parâmetro de matriz contendo esses 2 valores (traço vai escrever Array para o paramater em tais casos). Há também outras maneiras de abordar esta questão, mas isso é toda uma questão diferente.

De qualquer forma. mensagens de rastreamento são úteis, mas neste caso foram energia prejudicial.

A lição que aprendi, logo notei que a saída de rastreio:. Às vezes suprimir uma mensagem de erro, por enquanto, é uma medida de abertura de batente útil para evitar mais danos

Na minha opinião eu não acho que é um caso de design de classe ruim. O erro em si foi desencadeado por um PDOException (edição timestamp passando de MySQL 5,6-5,7) que simplesmente despejado por PHP padrão tudo em log de erros.

Em geral eu não usar o operador @ para todas as razões explicadas em outros comentários, mas neste caso o log de erro me convenceu a fazer algo rápido até que o problema foi montada correctamente.

Eu uso ele ao tentar carregar um arquivo HTML para o processamento como um objeto DOMDocument. Se houver quaisquer problemas no HTML ... e que o site não tem pelo menos um ... DOMDocument-> loadHTMLFile () irá lançar um erro se você não suprimi-lo com @ . Esta é a única maneira (talvez há melhores os) que eu já sido bem sucedida na criação de raspadores HTML em PHP.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top