Я видел использование @
перед определенными функциями, например:
$fileHandle = @fopen($fileName, $writeAttributes);
Каково использование этого символа?
Я видел использование @
перед определенными функциями, например:
$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(), который будет 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;
}
Также обратите внимание, что, несмотря на скрытые ошибки, любой пользовательский обработчик ошибок (установленный с помощью set_error_handler
) будет выполняться!
Как и раньше, некоторые ответили ранее: оператор @
подавляет все ошибки в PHP, включая уведомления, предупреждения и даже критические ошибки.
НО: Пожалуйста, действительно не используйте оператор @
вообще.
Почему?
Хорошо, потому что, когда вы используете оператор @
для подавления ошибок, у вас нет никакой подсказки, где начать, когда возникает ошибка. У меня уже было "забавное" с унаследованным кодом, где некоторые разработчики часто использовали оператор @
. Особенно в таких случаях, как операции с файлами, сетевые вызовы и т.д. Это все случаи, когда многие разработчики рекомендуют использовать оператор @
, поскольку это иногда выходит за пределы области действия, когда здесь возникает ошибка (например, API-интерфейс 3rdparty может быть недоступен и т.д.).
Но какой смысл по-прежнему не использовать его? Давайте взглянем с двух сторон:
Как разработчик: Когда используется @
, я не знаю, с чего начать. Если есть сотни или даже тысячи вызовов функций с помощью @
, ошибка может быть такой же, как и все. В этом случае нет разумной отладки. И даже если это всего лишь ошибка 3rdparty - тогда это просто отлично, и вы закончили быстро.;-) Более того, лучше добавить в журнал ошибок достаточно подробностей, поэтому разработчики могут легко решить, если запись в журнале - это что-то, что должно быть проверено дальше, или если это просто отказ третьей стороны, выходящий за рамки разработчика.
Как пользователь: Пользователям не важно, какая причина для ошибки. Программное обеспечение там для них работать, заканчивать конкретную задачу и т.д. Им все равно, если это ошибка разработчика или проблема с 3-ей партией. Особенно для пользователей, я настоятельно рекомендую регистрировать все ошибки, даже если они выходят за рамки. Возможно, вы заметите, что определенный API часто отключается. Что ты можешь сделать? Вы можете поговорить с вашим партнером по API, и если они не смогут сохранить стабильность, вам, вероятно, следует искать другого партнера.
Вкратце:. Вы должны знать, что существует нечто вроде @
(знание всегда хорошее), но просто не использовать его. Многие разработчики (особенно те, которые отлаживают код от других) будут очень благодарны.
Если сбой открытия не выполняется, генерируется ошибка уровня E_WARNING. Вы можете использовать @для подавления этого предупреждения.
Предположим, что мы не использовали оператор "@", тогда наш код выглядел бы так:
$fileHandle = fopen($fileName, $writeAttributes);
А что, если файл, который мы пытаемся открыть, не найден? Появится сообщение об ошибке.
Чтобы подавить сообщение об ошибке, мы используем оператор "@", например:
$fileHandle = @fopen($fileName, $writeAttributes);
"@" подавляет сообщения об ошибках.
Он используется в фрагментах кода, например:
@file_get_contents('http://www.exaple.com');
Если домен " http://www.exaple.com" недоступен, будет отображаться ошибка, но с "@" ничего не отображается.
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 умрет прямо там без указание о том, почему.
Возможно, стоит добавить здесь несколько указателей при использовании @, о котором вы должны знать, для полного прогона вниз этот пост: http://mstd.eu/index.php/2016/06/30/php-rapid-fire-what-is-the-symbol-used-for-in-php/
Обработчик ошибок все еще запущен даже с добавленным символом @, это просто означает, что установлен уровень ошибки 0, это должно быть надлежащим образом обработано в настраиваемом обработчике ошибок.
Предоставление include с @будет устанавливать все ошибки в файле include на уровень ошибки 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";