Каково использование символа @ в PHP?

Я видел использование @ перед определенными функциями, например:

 $fileHandle = @fopen($fileName, $writeAttributes); 

Какой смысл использовать этот символ?

Он подавляет сообщения об ошибках – см. « Операторы контроля ошибок» в руководстве по PHP.

Он подавляет ошибки.

Инструкции по управлению ошибками см. В руководстве:

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

Если вы задали функцию обработчика ошибок с помощью set_error_handler (), она все равно будет вызвана, но этот настраиваемый обработчик ошибок может (и должен) вызывать функцию error_reporting (), которая будет возвращать 0, когда вызову, вызвавшему ошибку, предшествовал символ @ …

Символ @ – это оператор управления ошибками (AKA – оператор «молчания» или «запирание»). Это заставляет PHP подавлять любые сообщения об ошибках (уведомление, предупреждение, фатальное и т. Д.), Генерируемое связанным выражением. Он работает точно так же, как унарный оператор. Например, он имеет приоритет и ассоциативность. Ниже приведены некоторые примеры:

 @echo 1 / 0; // Generates "Parse error: syntax error, unexpected T_ECHO" since // echo is not an expression echo @(1 / 0); // Suppressed "Warning: Division by zero" @$i / 0; // Suppressed "Notice: Undefined variable: i" // Displayed "Warning: Division by zero" @($i / 0); // Suppressed "Notice: Undefined variable: i" // Suppressed "Warning: Division by zero" $c = @$_POST["a"] + @$_POST["b"]; // Suppressed "Notice: Undefined index: a" // Suppressed "Notice: Undefined index: b" $c = @foobar(); echo "Script was not terminated"; // Suppressed "Fatal error: Call to undefined function foobar()". // However, PHP did not "ignore" the error and terminated the // script because the error was "fatal". 

Что именно происходит, если вы используете собственный обработчик ошибок вместо стандартного обработчика ошибок PHP:

Если вы задали функцию обработчика ошибок с помощью set_error_handler (), она все равно будет вызвана, но этот настраиваемый обработчик ошибок может (и должен) вызывать функцию error_reporting (), которая будет возвращать 0, когда вызову, вызвавшему ошибку, предшествовал символ @ ,

Это проиллюстрировано в следующем примере кода:

 function bad_error_handler($errno, $errstr, $errfile, $errline, $errcontext) { echo "[bad_error_handler]: $errstr"; return true; } set_error_handler("bad_error_handler"); echo @(1 / 0); // prints "[bad_error_handler]: Division by zero" 

Обработчик ошибок не проверял, действует ли символ @ . В руководстве предлагается следующее:

 function better_error_handler($errno, $errstr, $errfile, $errline, $errcontext) { if (error_reporting() !== 0) { echo "[better_error_handler]: $errstr"; } // Take appropriate action return true; } 

Также обратите внимание, что, несмотря на скрытые ошибки, любой пользовательский обработчик ошибок (установленный с помощью set_error_handler ) все равно будет выполнен!

Как и раньше, некоторые ответили ранее: оператор @ подавляет все ошибки в PHP, включая уведомления, предупреждения и даже критические ошибки.

НО: Пожалуйста, действительно не используйте оператор @ вообще.

Зачем?

Хорошо, потому что, когда вы используете оператор @ для подавления ошибок, у вас нет никакой подсказки, где начать, когда возникает ошибка. У меня уже было «забавное» с унаследованным кодом, где некоторые разработчики часто использовали оператор @ . Особенно в таких случаях, как операции с файлами, сетевые вызовы и т. Д. Это все случаи, когда многие разработчики рекомендуют использовать оператор @ поскольку это иногда выходит за пределы области видимости при возникновении ошибки (например, API-интерфейс 3rdparty может быть недоступен и т. Д.). .).

Но в чем смысл все еще не использовать его? Давайте посмотрим с двух точек зрения:

Как разработчик: Когда используется @ , я не знаю, с чего начать. Если есть сотни или даже тысячи вызовов функций с @ ошибка может быть такой же, как и все. В этом случае нет разумной отладки. И даже если это всего лишь ошибка 3rdparty – тогда это просто отлично, и вы закончили быстро. 😉 Кроме того, лучше добавить достаточное количество подробностей в журнал ошибок, поэтому разработчики могут легко решить, если запись в журнале – это что-то, что должно быть проверено дальше, или если это просто отказ третьей стороны, который выходит за рамки разработчика.

Как пользователь: пользователям все равно, какова причина ошибки или нет. Программное обеспечение там для работы, для завершения конкретной задачи и т. Д. Им все равно, является ли это ошибкой разработчика или проблемой третьего участника. Особенно для пользователей, я настоятельно рекомендую регистрировать все ошибки, даже если они выходят за рамки. Возможно, вы заметите, что определенный API часто отключается. Что ты можешь сделать? Вы можете поговорить с партнером по API, и если они не смогут сохранить стабильность, вам, вероятно, следует искать другого партнера.

Короче: вы должны знать, что существует нечто вроде @ (знание всегда хорошее), но просто не используйте его . Многие разработчики (особенно те, которые отлаживают код от других) будут очень благодарны.

Если сбой открытия, генерируется ошибка уровня E_WARNING. Вы можете использовать @ для подавления этого предупреждения.

Предположим, что мы не использовали оператор «@», тогда наш код выглядел бы так:

 $fileHandle = fopen($fileName, $writeAttributes); 

И что, если файл, который мы пытаемся открыть, не найден? Появится сообщение об ошибке.

Чтобы подавить сообщение об ошибке, мы используем оператор «@», например:

 $fileHandle = @fopen($fileName, $writeAttributes); 

«@» подавляет сообщения об ошибках.

Он используется в фрагментах кода, таких как:

 @file_get_contents('http://www.exaple.com'); 

Если домен « http://www.exaple.com » недоступен, будет отображаться ошибка, но с «@» ничего не отображается.

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

Если вы задали функцию обработчика ошибок с помощью set_error_handler() она все равно будет вызвана, но этот настраиваемый обработчик ошибок может (и должен) вызывать error_reporting() которая будет возвращать 0 когда вызову, вызвавшему ошибку, предшествовал символ @ ,

 <?php /* Intentional file error */ $my_file = @file ('non_existent_file') or die ("Failed opening file: error was '$php_errormsg'"); // this works for any expression, not just functions: $value = @$cache[$key]; // will not issue a notice if the index $key doesn't exist. ?> 

Заметка:-

1) @ -оператор работает только с выражениями.

2) Простое эмпирическое правило: если вы можете принять значение чего-то, вы можете добавить к нему оператор @. Например, вы можете добавить его к переменным, функциям и включить вызовы, константы и т. Д. Вы не можете добавлять его к определениям функций или классов или условным структурам, таким как if и foreach, и так далее.

Предупреждение:-

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

Возможно, стоит добавить здесь несколько указателей при использовании @, о которых вы должны знать, для полного прохода вниз этот пост: http://mstd.eu/index.php/2016/06/30/php- скоропалительный-что-это-The-символ используется для-в-PHP /

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

  2. Предоставление include с @ будет устанавливать все ошибки в файле include на уровень ошибки 0