Какая польза от символа @ в PHP?

426

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

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

Каково использование этого символа?

  • 3
    И RichieHindle, и Aiden Bell дали правильный ответ, но, поскольку я могу принять только один ответ в качестве принятого, я выберу первый. Прости эйден
  • 1
    Подавление ошибок (хотя и неплохое) может привести к ошибкам в будущем при поддержке кодовой базы ... stackoverflow.com/a/7116175/282343
Теги:
operators

11 ответов

485
Лучший ответ

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

  • 38
    Это было что-то вроде быстрого розыгрыша!
  • 6
    Да уж; вплоть до второго! Я должен был проверить идентификатор ответа, чтобы увидеть, кто пришел первым :)
Показать ещё 3 комментария
347

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

См. Операторы контроля ошибок в руководстве:

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

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

  • 141
    проголосовал только потому, что другой ответ получает всю любовь.
  • 6
    @ ajacian81 - Ура!
Показать ещё 3 комментария
173

Символом @ является управление ошибкой (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(), который будет return 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;
}
  • 33
    Самый подробный и информативный ответ здесь.
  • 4
    Очень информативно.
Показать ещё 3 комментария
52

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

21

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

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

Почему?

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

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

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

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

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

  • 1
    Некоторые предупреждения могут быть надежно подавлены только с помощью @ (например, fopen (), где любая попытка предсказать результат зависит от состояния гонки), если у вас есть код для обработки условия ошибки более аккуратным способом, тогда usuig @ - правильная вещь действительно, это особенно полезно, особенно если вы не возвращаете text/html (или подобный) клиенту. (возможно возвращая image/png или "JSON")
  • 1
    Вы не должны подавлять предупреждения - они заявляют, что вы сделали что-то не так. Нет такого состояния гонки, при котором вы не можете правильно проверить или обработать состояние.
Показать ещё 4 комментария
5

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

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

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

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

$fileHandle = @fopen($fileName, $writeAttributes);
  • 0
    Это прекрасный пример того, почему PHP имеет такой @ обходной путь. Другие языки программирования имеют одинаковую обработку исключений, чтобы справиться с этим сценарием stackoverflow.com/questions/1087365
5

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

2

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

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

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

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

1

Возможно, стоит добавить здесь несколько указателей при использовании @, о котором вы должны знать, для полного прогона вниз этот пост: http://mstd.eu/index.php/2016/06/30/php-rapid-fire-what-is-the-symbol-used-for-in-php/

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

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

1

PHP поддерживает один оператор управления ошибкой: знак (@). При добавлении выражения в 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, и т.д.

Внимание: -

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

0

Я лично использую этот оператор для определенных соединений SQL и избегаю isset(), используя методы post/get из форм, потому что иногда они становятся раздражающими, когда их связывают.

if (isset($_POST["submit"])) echo "defined"; // standard condition
else echo "undefined";

if (@$_POST["submit"]) echo "defined"; // normally it would cause notice error
else echo "undefined";

echo isset($_POST["submit"]) ? "defined" // ternary condition
: "undefined";

echo @$_POST["submit"] ? "defined" // normally it would cause notice error
: "undefined";

Ещё вопросы

Сообщество Overcoder
Наверх
Меню