Подавить ошибку с помощью оператора @ в PHP [закрыто]
на ваш взгляд, можно ли использовать оператор @ для подавления ошибки / предупреждения в PHP, в то время как вы можете обрабатывать ошибку?
Если да, то при каких обстоятельствах вы бы это использовали?
примеры кода приветствуются.
Edit: Примечание Для репликаторов. Я не хочу отключать отчеты об ошибках, но, например, обычной практикой является использование
@fopen($file);
и потом проверить... но вы можете избавиться от @ по делать
if (file_exists($file))
{
fopen($file);
}
else
{
die('File not found');
}
или аналогичные.
Я думаю, вопрос в том-есть ли где-нибудь, что @ должен использоваться для подавления ошибки, которая не может быть обработана каким-либо другим способом?
14 ответов:
Я бы подавил ошибку и справиться с этим. В противном случае вы можете иметь TOCTOU проблема (время проверки, время использования. Например, файл может быть удален после того, как file_exists возвращает true, но до fopen).
но я бы не просто подавлял ошибки, чтобы заставить их уйти. Эти лучше быть видимыми.
Примечание: во-первых, я понимаю, что 99% разработчиков PHP используют оператор подавления ошибок (я раньше был одним из них), поэтому я ожидаю, что любой разработчик PHP, который видит это, не согласится.
на ваш взгляд, можно ли использовать оператор @ для подавления ошибки / предупреждения в PHP, в то время как вы можете обрабатывать ошибку?
короткий ответ:
Нет!уже более правильный ответ:
Я не знаю, как и я не знаю знаю все, но до сих пор я не сталкивался с ситуацией, когда это было хорошим решением.почему это плохо:
В том, что я думаю о 7 годах использования PHP теперь я видел бесконечную агонию отладки, вызванную оператором подавления ошибок, и никогда не сталкивался с ситуацией, когда это было неизбежно.проблема в том, что часть кода, для которой вы подавляете ошибки, может в настоящее время вызывать только ту ошибку, которую вы видите; однако при изменении код, на который опирается подавленная строка, или среда, в которой она выполняется, тогда есть все шансы, что строка попытается вывести совершенно другую ошибку, чем та, которую вы пытались игнорировать. Тогда как вы отслеживаете ошибку, которая не выводится? Добро пожаловать в ад отладки!
альтернативы (в зависимости от ситуации и желаемого результата):
Обработайте фактическую ошибку, о которой вы знаете, так что если кусок кода вызовет определенная ошибка, то он не запускается в этой конкретной ситуации. Но я думаю, что вы получаете эту часть, и вы просто беспокоились о том, что конечные пользователи видят ошибки, которые я сейчас рассмотрю.для обычных ошибок вы можете настроить обработчик ошибок, чтобы они выводились так, как вы хотите, когда вы просматриваете страницу, но скрыты от конечных пользователей и зарегистрированы, чтобы вы знали, какие ошибки запускают ваши пользователи.
для фатальных ошибок set
display_errorsto off (ваш обработчик ошибок все равно срабатывает) в вашем php.ini и включить ведение журнала ошибок. Если у вас есть сервер разработки, а также живой сервер (который я рекомендую), то этот шаг не нужен на вашем сервере разработки, поэтому вы все равно можете отлаживать эти фатальные ошибки, не прибегая к просмотру файла журнала ошибок. Есть даже трюк с помощью функции отключения для отправки большого количества фатальных ошибок в обработчик ошибок.в итоге:
Пожалуйста, избегайте оно. Возможно, для этого есть веская причина, но я еще не вижу ее, поэтому до этого дня я считаю, что оператор подавления ошибок (@) является злым.вы можете узнать мой комментарий на странице операторы контроля ошибок в руководстве PHP, если вы хотите получить больше информации.
Да подавление смысл.
например,
fopen()команда возвращаетFALSEесли файл не может быть открыт. Это нормально, но это и выдает предупреждение PHP. Часто вы не хотите предупреждение - вы будете проверятьFALSEсебя.В самом деле руководство PHP специально предлагает использовать @ в этом случае!
Если вы не хотите выдавать предупреждение при использовании таких функций, как fopen (), вы можете подавить ошибку, но использовать исключения:
try { if (($fp = @fopen($filename, "r")) == false) { throw new Exception; } else { do_file_stuff(); } } catch (Exception $e) { handle_exception(); }
подавление ошибок следует избегать, если вы знаю вы можете справиться со всеми условиями.
Это может быть намного сложнее, чем кажется на первый взгляд.
то, что вы действительно должны сделать, это полагаться на php "error_log", чтобы быть вашим методом отчетности, так как вы не можете полагаться на пользователей, просматривающих страницы, чтобы сообщать об ошибках. (И вы также должны отключить php от отображения этих ошибок )
тогда, по крайней мере, у вас будет полный отчет обо всем происходящем неправильно в системе.
Если вы действительно должны обрабатывать ошибки, вы можете создать пользовательский обработчик ошибок
http://php.net/set-error-handler
тогда вы можете отправить исключения (которые могут быть обработаны ) и сделать все необходимое, чтобы сообщить о странных ошибках администрации.
Я никогда не позволяю себе использовать '@'... период.
когда я обнаруживаю использование ' @ ' в коде, я добавляю комментарии, чтобы сделать его очевидным, как в точке использования, так и в docblock вокруг функции, где он используется. Я тоже был укушен отладкой "chasing a ghost" из-за такого подавления ошибок, и я надеюсь облегчить его для следующего человека, выделив его использование, когда я его найду.
в тех случаях, когда я хочу, чтобы мой собственный код кинуть Исключение если собственная функция 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();
большинство людей не понимают смысла сообщения об ошибке.
Без шуток. Большинство из них.Они думают, что сообщения об ошибках все одинаковы, говорит: "что-то идет не так!"
Они не утруждают себя чтением.
Хотя это самая важная часть сообщения об ошибке-не только тот факт, что он был поднят, но и его смысл. Он может сказать вам что идет не так. Сообщения об ошибках предназначены для помощи, а не для того, чтобы беспокоить вас "как это скрыть?" проблема. Это одна из самых больших недоразумений в мире веб-программирования новичков.таким образом, вместо сообщения об ошибке кляпа, следует читать что там написано. Он имеет не только одно значение "файл не найден". Там могут быть тысячи различных ошибок:
permission denied,save mode restriction,open_basedir restrictionetc.так далее. Каждый из них требует соответствующих действий. но если вы заткнете его, вы никогда не узнаете, что произошло!ОП портит ошибку отчетность с ошибкой обращение, а это очень большая разница!
Обработка ошибок предназначена для пользователя. "что-то случилось" здесь достаточно.
В то время как сообщение об ошибке для программиста, который отчаянно нуждается, чтобы знать, что, безусловно, произошло.таким образом, никогда не кляп сообщения об ошибках. Оба журнал для программиста, и справиться с этим для пользователей.
нет ли способа подавить из php.ini предупреждения и ошибки? в этом случае вы можете отлаживать только изменение флага и не пытаться обнаружить, какой @ скрывает проблему.
использование @ иногда контрпродуктивно. По моему опыту, вы всегда должны отключать отчеты об ошибках в php.ini или call
error_reporting(0);на производственной площадке. Таким образом, когда вы находитесь в, вы можете просто закомментировать строку и сохранить видимые ошибки для отладки.
единственное место, где мне действительно нужно было использовать это функция eval. Проблема с eval заключается в том, что, когда строка не может быть проанализирована из-за синтаксической ошибки, eval не возвращает false, а скорее выдает ошибку, точно так же, как ошибка синтаксического анализа в обычном скрипте. Для того, чтобы проверить, является ли скрипт, хранящийся в строке, разбираемым, вы можете использовать что-то вроде:
$script_ok = @eval('return true; '.$script);AFAIK, это самый элегантный способ сделать это.
одно место, где я использую его, находится в коде сокета, например, если у вас установлен тайм-аут, вы получите предупреждение об этом, если вы не включаете@, даже если он действителен, чтобы не получить пакет.
$data_len = @socket_recvfrom( $sock, $buffer, 512, 0, $remote_host, $remote_port )
вы не хотите подавлять все, так как это замедляет ваш скрипт.
и да, есть способ, как в PHP.ini и в вашем скрипте, чтобы удалить ошибки (но только делать это, когда вы находитесь в живой среде и регистрировать свои ошибки из php)
<?php error_reporting(0); ?>и вы можете читать этой для php.ini-версия отключения.
Если вы используете пользовательскую функцию обработки ошибок и хотите подавить ошибку (возможно, известную ошибку), используйте этот метод. Использование ' @ ' не является хорошей идеей в этом контексте, поскольку он не будет подавлять ошибку, если установлен обработчик ошибок.
напишите 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 }
Я использую его при попытке загрузить HTML-файл для обработки в качестве объекта DOMDocument. Если есть какие-либо проблемы в HTML... а какой сайт не имеет хотя бы один... DOMDocument - >loadHTMLFile () выдаст ошибку, если вы не подавите ее с помощью @. Это единственный способ (возможно, есть и лучшие), который я когда-либо успешно создавал HTML-скребки в PHP.
Comments