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


577

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

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

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


3
И РичиХиндл, и Эйден Белл дали правильный ответ, но, поскольку я могу принять только один ответ в качестве принятого, я выберу первый. Извините, Эйден
sv_in

1
Подавление ошибок (хотя это и хорошо) может привести к ошибкам в будущем при поддержке кодовой базы ... stackoverflow.com/a/7116175/282343
dennismonsewicz

Ответы:


636

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


46
Это было что-то вроде быстрого розыгрыша!
Эйден Белл

6
Да; вплоть до второго! Я должен был проверить идентификаторы ответов, чтобы увидеть, кто пришел первым :)
Sampson

3
У меня было время, чтобы исправить свое подавление орфографии после публикации ... и, черт побери, за то, что вы совершенствуетесь с помощью ссылки, в то же время бесится : P
Эйден Белл

1
Классная особенность. Это делает использование isset()ненужным, чтобы избежать undefined offsetошибок.
WM

470

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

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

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

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


157
проголосовал только потому, что другой ответ получает всю любовь.
ajacian81

10
19 позади ... давай люди, давайте победим RichieHindle: P
Эйден Белл

Этот ответ был первым (в контексте с тем, кто ответил на него первым).
Мохд Абдул Муджиб

227

@Символ является контроль ошибок оператора ( так называемый «молчание» или «закрыты вверх» оператор). Это заставляет 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;
}

58

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


34

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

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

Почему?

Ну, потому что, когда вы используете @оператор для подавления ошибок, вы совершенно не представляете, с чего начать при возникновении ошибки. Я уже немного повеселился с унаследованным кодом, когда некоторые разработчики использовали @оператор довольно часто. Особенно в таких случаях, как файловые операции, сетевые вызовы и т. Д. Все эти случаи, когда многие разработчики рекомендуют использовать @оператор, поскольку это иногда выходит за рамки возможного, когда здесь происходит ошибка (например, API-интерфейс третьей стороны может быть недоступен и т. Д.). ).

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

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

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

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


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

1
Вы не должны подавлять предупреждения - они заявляют, что вы сделали что-то не так. Нет такого состояния гонки, при котором вы не можете правильно проверить или обработать состояние.
Райан Рентфро

1
У меня есть следующее в моем коде в нескольких местах. if( session_status() == PHP_SESSION_NONE ) session_start(); Это унаследованное приложение, которое я унаследовал, и есть места, где скрипт установки вызывается несколько раз, поэтому я должен протестировать. Какая, если есть, проблема будет в простом использовании @session_start();?
Стивен Р

Если вы знаете, что делаете, и используете это экономно / стратегически, это стоит использовать. @$this->stats['device_os'][$date][$creative_id][$device_id][$operating_system]['clicks']++;это намного лучше, чем альтернатива иметь проверки isset на каждом уровне и заполнять его, когда это не так.
dtbarne

1
Дайте мне вескую причину, почему стоит добавить более 12 строк кода и не добавлять никакого значения, а только уменьшать читабельность и краткость кода, кроме того, что вы где-то когда-то читали, что он «грязный» и, возможно, вы можете передумать.
dtbarne

7

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

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

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

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

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

Это прекрасный пример того, почему PHP имеет такой @обходной путь. Другие языки программирования имеют одинаковую обработку исключений для работы с подобным сценарием stackoverflow.com/questions/1087365
dreftymac

@dreftymac Точно!
Суджит Кумар,

5

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


5

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

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

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

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


1

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, и так далее.

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

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


1

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

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

  2. При добавлении с помощью @ все ошибки во включаемом файле будут установлены на уровень ошибок 0


1

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.