2008-09-25 4 views
60

Как вы считаете, действительно ли используется оператор @ для подавления ошибки/предупреждения на PHP, тогда как вы можете обрабатывать ошибку?Подавить ошибку с помощью оператора @ в PHP

Если да, то в каких обстоятельствах вы бы это использовали?

Примеры кода приветствуются.

Редактировать: Замечание для ответчиков. Я не ищу, чтобы включить сообщения об ошибках прочь, но, например, обычной практикой является использование

@fopen($file); 

, а затем проверить после ... но вы можете избавиться от @ делая

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

или аналогичный.

У меня вопрос: есть ли где-нибудь, что @ ПРИНИМАЕТСЯ, чтобы подавить ошибку, которая НЕ МОЖЕТ быть обработана каким-либо другим способом?

+6

Ваш пример не работает; «Файл не найден» - это не единственный способ, с помощью которого fopen() может выйти из строя. Возможно, файл не читается. Возможно, это открыто другим процессом. Условия ошибки зависят от платформы, и в любом случае вы можете не тратить время на то, чтобы задуматься о случаях отказа. – 2008-09-26 01:45:27

+0

см. Также: http://stackoverflow.com/questions/1087365 – dreftymac 2011-10-11 17:33:31

+4

и почему взломать этот вопрос закрыт ?? – GOD 2013-05-04 18:11:07

ответ

23

Я бы подавляющая ошибку и обрабатывать его , В противном случае у вас может быть проблема TOCTOU (время проверки, время использования. Например, файл может быть удален после того, как file_exists вернет true, но до fopen).

Но я бы не просто подавил ошибки, чтобы заставить их уйти. Это лучше видно.

19

Да, подавление имеет смысл.

Например, команда fopen() возвращает FALSE, если файл не может быть открыт. Это нормально, но это также создает предупреждающее сообщение PHP. Часто вы не хотите предупреждения - вы сами проверите FALSE.

Фактически PHP manual специально предлагает использовать @ в этом случае!

+3

, но этого можно избежать, сначала проверив файл_exists ($ file)? – Mez 2008-09-26 01:03:33

+14

Нет, он не может, существуют другие условия сбоя, такие как «нет разрешений на чтение» или «файл занят». – 2008-09-26 01:46:01

+3

Это здорово, пока fopen не выдает ошибку, которую вы не ожидали. Вы не можете проверить все свои известные условия ошибки? Создайте функцию обертки fopen. – Gerry 2012-01-28 04:49:22

3

Не существует способа подавить предупреждения и ошибки php.ini? в этом случае вы можете отлаживать только изменение флага и не пытаться обнаружить, что @ скрывает проблему.

+0

да, вы можете сделать error_reporting (E_ALL & ~ E_NOTICE & ~ E_WARNING) - но я не хочу этого делать, см. Отредактированный вопрос – Mez 2008-09-26 01:17:17

1

Вы не хотите подавлять все, так как это замедляет ваш скрипт.

И да есть способ, как в php.ini и в вашем скрипте для устранения ошибок (но только делать это, когда вы находитесь в реальной среде и войти ваши ошибки от PHP)

<?php 
    error_reporting(0); 
?> 

А ты может читать this для версии php.ini отключения.

+0

Я не ищу способ отключить его, я ищу, есть причина использовать его, как во всем, что невозможно обработать без использования @ (один элемент до сих пор - mysql_connect) – Mez 2008-09-26 01:14:54

6

Следует избегать подавления ошибок, если вы не знаете , вы можете обрабатывать все условия.

Это может быть намного сложнее, чем кажется на первый взгляд.

Что вы действительно должны делать, это полагаться на «error_log» php, чтобы быть вашим методом отчетности, так как вы не можете полагаться на просмотр пользователями страниц, чтобы сообщать об ошибках. (И вы также должны отключить php от отображения этих ошибок)

Тогда, по крайней мере, у вас будет исчерпывающий отчет о всех ошибках в системе.

Если вы действительно должны обрабатывать ошибки, вы можете создать обработчик ошибок

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

Тогда вы могли бы послать исключения (которые могут быть обработаны) и сделать что-нибудь необходимое, чтобы сообщить странные ошибки в управлении ,

-1

Я использую его при попытке загрузить файл HTML для обработки в качестве объекта DOMDocument. Если в HTML есть какие-то проблемы ... и на каком веб-сайте нет хотя бы один ... DOMDocument-> loadHTMLFile() выдает ошибку, если вы не подавите ее с помощью @. Это единственный способ (возможно, лучшие). Мне когда-либо удавалось создавать HTML-скребки в PHP.

3

Использование @ иногда встречается продуктивно. По моему опыту, вы всегда должны отключать отчет об ошибках в php.ini или звонить

error_reporting(0); 

на производственной площадке. Таким образом, когда вы находитесь в разработке, вы можете просто прокомментировать строку и сохранить видимые ошибки для отладки.

2

Одно место, которое я использую в коде сокета, например, если у вас установлен тайм-аут, вы получите предупреждение об этом, если вы не включили @, даже если это действительно так, чтобы не получить пакет.

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

Если вы не хотите, предупреждения выдается при использовании функции как FOPEN(), вы можете подавить ошибку, но использовать исключение:

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

Примечание: во-первых, я понимаю, что 99% разработчиков PHP используют оператор подавления ошибок (я был одним из них), поэтому я ожидаю, что любой PHP-разработчик увидит, что это не согласуется.

Как вы считаете, действительно ли используется оператор @ для подавления ошибки/предупреждения на PHP, тогда как вы можете обрабатывать ошибку?

Короткий ответ:
Нет!

Longer более правильный ответ:
Я не знаю, как я не знаю все, но до сих пор я не сталкивался с ситуацией, когда это было хорошим решением.

Почему это плохо:
В то, что я думаю, что около 7 лет, используя PHP теперь я видел бесконечные отладки агонии, вызванной оператором подавления ошибок и никогда не сталкивался с ситуацией, когда это было неизбежно.

Проблема в том, что фрагмент кода, который вы подавляете ошибки, в настоящее время может вызывать только ошибку, которую вы видите; однако, когда вы меняете код, на который полагается подавленная линия, или среда, в которой она выполняется, тогда есть все шансы, что линия попытается вывести совершенно другую ошибку из той, которую вы пытались игнорировать. Тогда как вы отслеживаете ошибку, которая не выводится? Добро пожаловать в отладку ада!

Мне потребовалось много лет, чтобы понять, сколько времени я трачу каждые пару месяцев из-за подавленных ошибок. Чаще всего (но не исключительно) это было после установки стороннего скрипта/приложения/библиотеки, которая была безошибочной в среде разработчиков, но не моя из-за разницы в конфигурации сервера или сервера или отсутствовала зависимость, которая могла бы нормально вывести ошибку немедленно предупреждая о проблеме, но не тогда, когда разработчик добавляет magic @.

альтернатив (в зависимости от ситуации и желаемого результата):
Handle фактической ошибки, что вы в курсе, так что, если кусок кода будет вызывать определенную ошибку, то она не выполняется в в этой конкретной ситуации. Но я думаю, что вы получаете эту часть, и вы просто беспокоились о том, что конечные пользователи видят ошибки, и это то, что я сейчас адресую.

Для регулярных ошибок вы можете настроить обработчик ошибок так, чтобы они отображались так, как вы хотите, когда вы просматриваете страницу, но скрыты от конечных пользователей и регистрируетесь, чтобы вы знали, какие ошибки запускают ваши пользователи.

Для фатальных ошибок установите display_errors в выключенном состоянии (ваш обработчик ошибок по-прежнему запускается) в вашем php.ini и включите ведение журнала ошибок. Если у вас есть сервер разработки, а также живой сервер (который я рекомендую), этот шаг не требуется на вашем сервере разработки, поэтому вы можете отлаживать эти фатальные ошибки, не прибегая к просмотру файла журнала ошибок. Есть даже trick using the shutdown function, чтобы отправить большое количество фатальных ошибок вашему обработчику ошибок.

В целом:
Пожалуйста, избегайте этого. Для этого может быть веская причина, но я еще не видел ее, поэтому до сих пор мое мнение о том, что оператор подавления ошибок (@) является злым.

В справочнике PHP вы можете прочитать my comment on the Error Control Operators page, если хотите получить дополнительную информацию.

6

Я НИКОГДА не позволяю себе использовать «@» ... период.

Когда я обнаруживаю использование кода «@» в коде, я добавляю комментарии, чтобы сделать его очевидным, как в точке использования, так и в docblock вокруг функции, в которой он используется. Я тоже был укушен отладкой «преследовать призрак» из-за такого подавления ошибок, и я надеюсь, что это станет проще для следующего человека, выделив его использование, когда я его найду.

В тех случаях, когда я хочу, чтобы мой собственный код выдавал исключение, если встроенная функция PHP встречает ошибку, а «@» - это простой способ, я вместо этого хочу сделать что-то еще, Такой же результат, но (опять же) явно проявляется в коде:

$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'); } 

это намного больше кода, просто писать:

$result = @native_func(); 

, но я предпочитаю, чтобы сделать мое подавление нужно ОЧЕНЬ оЧЕВИДНО, ради плохой отладочной души, которая следует за мной.

3

Единственное место, где мне действительно нужно было использовать его, является функция eval. Проблема с eval заключается в том, что, когда строка не может быть проанализирована из-за ошибки синтаксиса, eval не возвращает false, а скорее выдает ошибку, точно так же, как наличие ошибки синтаксического анализа в регулярном скрипте. Для того, чтобы проверить скрипт хранится в строке, является ли распознаваем вы можете использовать что-то вроде:

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

AFAIK, это самый элегантный способ сделать это.

0

Если вы используете пользовательскую функцию обработки ошибок и хотите подавить ошибку (возможно, известную ошибку), используйте этот метод. Использование «@» не является хорошей идеей в этом контексте, поскольку оно не будет подавлять ошибку, если установлен обработчик ошибок.

Напишите 3 функции и вызовите это.

# 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 
} 
4

Большинство людей не понимают значения сообщения об ошибке.
Не шутить. Большинство из них.

Они считают, что сообщения об ошибках одинаковы, говорит: «Что-то не так!»
Они не удосужились его прочитать.
Хотя это самая важная часть сообщения об ошибке, а не только тот факт, что она была поднята, но это значение. Он может сообщить вам , что идет не так. Сообщения об ошибках предназначены для помощи, а не для того, чтобы беспокоить вас «как скрыть это?». проблема. Это одно из самых больших недоразумений в мире веб-программирования новичка.

Таким образом, вместо сообщения об ошибке gagging следует читать, что он говорит. Он имеет не только одно значение «файл не найден». Возможны тысячи различных ошибок: permission denied, save mode restriction, open_basedir restriction и т.п.etc. Каждый из них требует соответствующих действий. Но если вы заткнитесь им, вы никогда не узнаете, что случилось!

ОП Мессинг ошибка отчетности с ошибкой обработки, в то время как это очень большая разница!
Обработка ошибок для пользователя. «что-то случилось» достаточно.
Пока сообщение об ошибках предназначено для программистов, которым отчаянно нужно знать, что именно произошло.

Таким образом, сообщения об ошибках никогда не появляются. Оба запишите его для программиста, и обработайте его для пользователя.

Смежные вопросы