Подавить ошибку с @ operator в PHP

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

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

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

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

@fopen($file); 

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

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

или похожие.

Я думаю, вопрос в том, есть ли где-нибудь, что @ HAS используется для подавления ошибки, которая НЕ МОЖЕТ быть обработана каким-либо другим способом?

Solutions Collecting From Web of "Подавить ошибку с @ operator в PHP"

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

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

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

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

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

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

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

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

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

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

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

Для фатальных ошибок отключите 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(); } 

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

Это может быть намного сложнее, чем сначала.

То, что вам действительно нужно сделать, зависит от «error_log» php, чтобы быть вашим методом отчетности, так как вы не можете полагаться на просмотр пользователями страниц для сообщения об ошибках. (И вы также должны отключить 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(); 

но я предпочитаю, чтобы мое подавление требовало ОЧЕНЬ ОБЫЧНО, ради бедной души отладки, которая следует за мной.

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

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

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

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

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

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

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

 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.