По вашему мнению, допустимо ли когда-либо использовать оператор @ для подавления ошибки / предупреждения в PHP, тогда как вы, возможно, обрабатываете ошибку?
Если да, то при каких обстоятельствах вы бы использовали это?
Примеры кода приветствуются.
Изменить: Примечание для ответчиков. Я не хочу отключать отчеты об ошибках, но, например, обычной практикой является использование
@fopen($file);
а затем проверить потом … но вы можете избавиться от @, выполнив
if (file_exists($file))
{
fopen($file);
}
else
{
die('File not found');
}
или похожие.
Я предполагаю, что вопрос — есть ли где-нибудь, что @ HAS будет использоваться для подавления ошибки, что НЕ МОЖЕТ быть обработано каким-либо другим способом?
Я бы подавил ошибку и справиться с этим. В противном случае вы можете иметь TOCTOU Проблема (время проверки, время использования. Например, файл может быть удален после того, как file_exists вернет true, но до fopen).
Но я не просто подавил бы ошибки, чтобы они ушли. Это лучше быть видимым.
Примечание: во-первых, я понимаю, что 99% разработчиков PHP используют оператор подавления ошибок (я был одним из них), поэтому я ожидаю, что любой разработчик PHP, который считает, что это не так.
По вашему мнению, допустимо ли когда-либо использовать оператор @ для подавления ошибки / предупреждения в PHP, тогда как вы, возможно, обрабатываете ошибку?
Короткий ответ:
Нет!
Более правильный ответ:
Я не знаю, потому что я не знаю всего, но до сих пор я не сталкивался с ситуацией, когда это было бы хорошим решением.
Почему это плохо
Я думаю, что за 7 лет использования PHP я видел бесконечную агонию отладки, вызванную оператором подавления ошибок, и никогда не сталкивался с ситуацией, когда это было неизбежно.
Проблема в том, что фрагмент кода, для которого вы подавляете ошибки, может в настоящее время вызывать только ту ошибку, которую вы видите; однако, когда вы изменяете код, на который опирается подавленная строка, или среду, в которой она выполняется, есть все шансы, что строка попытается вывести совершенно другую ошибку из той, которую вы пытались игнорировать. Тогда как вы отслеживаете ошибку, которая не выводится? Добро пожаловать в ад отладки!
Мне потребовалось много лет, чтобы понять, сколько времени я трачу каждые пару месяцев из-за скрытых ошибок. Чаще всего (но не исключительно) это происходило после установки стороннего скрипта / приложения / библиотеки, которая не содержала ошибок в среде разработчиков, но не моя из-за разницы в конфигурации php или сервера или отсутствующей зависимости, которая обычно выдает ошибку сразу оповещение о том, в чем проблема, но не когда разработчик добавляет магию @.
Альтернативы (в зависимости от ситуации и желаемого результата):
Обработайте фактическую ошибку, о которой вы знаете, так что, если фрагмент кода вызовет определенную ошибку, он не будет запущен в этой конкретной ситуации. Но я думаю, что вы получили эту часть, и вы просто волновались, что конечные пользователи увидят ошибки, и это то, что я сейчас рассмотрю.
Для обычных ошибок вы можете настроить обработчик ошибок так, чтобы они выводились так, как вы хотите, когда вы просматриваете страницу, но скрыты от конечных пользователей и регистрируются, чтобы вы знали, какие ошибки вызывают ваши пользователи.
Для фатальных ошибок установлено display_errors
выключить (ваш обработчик ошибок все еще срабатывает) в вашем 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
Затем вы можете отправить исключения (которые могут быть обработаны) и сделать все необходимое, чтобы сообщить администрации о странных ошибках.
Я НИКОГДА не позволяю себе использовать ‘@’ … точка.
Когда я обнаруживаю использование «@» в коде, я добавляю комментарии, чтобы сделать его наглядным, как в момент использования, так и в блоке документации вокруг функции, в которой он используется. Я тоже был укушен отладкой «погони за призраком» из-за такого рода подавления ошибок, и я надеюсь облегчить задачу следующему человеку, подчеркнув его использование, когда я его найду.
В тех случаях, когда я хочу, чтобы мой собственный код выдавал исключение, если нативная функция 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 restriction
etc.etc. Каждый из них требует соответствующих действий. Но если ты заткнешь рот, то никогда не узнаешь, что случилось!
ОП портит ошибку составление отчетов с ошибкой обращение, пока это очень большая разница!
Обработка ошибок для пользователя. «что-то случилось» здесь достаточно.
В то время как сообщение об ошибке предназначено для программиста, которому крайне необходимо знать, что именно произошло.
Таким образом, никогда не заглатывайте сообщения об ошибках. И то и другое войти это для программиста и справиться для пользователя.
нет ли способа подавить из php.ini предупреждения и ошибки? в этом случае вы можете отлаживать только изменяя флаг и не пытаясь определить, какой @ скрывает проблему.