Jakie jest użycie symbolu @ w PHP?

577

Widziałem zastosowania @przed niektórymi funkcjami, takimi jak:

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

Do czego służy ten symbol?

sv_in
źródło
3
Zarówno RichieHindle, jak i Aiden Bell udzielili prawidłowej odpowiedzi, ale ponieważ mogę ustawić tylko jedną odpowiedź jako wybraną, wybiorę pierwszą. Przepraszamy Aiden
sv_in 30.09.09
1
Pomijanie błędów (chociaż miłe) może powodować błędy w
dalszej

Odpowiedzi:

636

Pomija komunikaty o błędach - patrz Operatory kontroli błędów w podręczniku PHP.

RichieHindle
źródło
46
To było trochę szybkie losowanie!
Aiden Bell
6
Tak; aż do sekundy! Musiałem sprawdzić id odpowiedzi, aby zobaczyć, kto wszedł pierwszy :)
Sampson
3
Miałem czas, aby poprawić pisownię po opublikowaniu ... i do cholery za ulepszenie za pomocą linku w tym samym czasie szaleje : P
Aiden Bell
1
Fajna funkcja .. To sprawia, że ​​korzystanie z isset()nie jest konieczne, aby uniknąć undefined offsetbłędów.
WM
470

Pomija błędy.

Zobacz Operatory kontroli błędów w instrukcji:

PHP obsługuje jeden operator kontroli błędów: znak at (@). Po dodaniu do wyrażenia w PHP wszelkie komunikaty o błędach, które mogą zostać wygenerowane przez to wyrażenie, zostaną zignorowane.

Jeśli ustawiłeś niestandardową funkcję obsługi błędów za pomocą funkcji set_error_handler () , nadal będzie ona wywoływana, ale ta niestandardowa procedura obsługi błędów może (i powinna) wywoływać error_reporting (), która zwróci 0, gdy wywołanie, które wywołało błąd, było poprzedzone znakiem @ ...

Aiden Bell
źródło
157
głosowałem tylko dlatego, że drugą odpowiedzią jest zdobycie całej miłości.
ajacian81,
10
19 za ... no dalej ludzie, pokonajmy RichieHindle: P
Aiden Bell
Ta odpowiedź była pierwsza (w kontekście tego, kto odpowiedział na nią jako pierwszy).
Mohd Abdul Mujib
227

@Symbolem jest kontrola błędu operatora (aka „cisza” lub „shut up” operator). To powoduje, że PHP pomija wszelkie komunikaty o błędach (zawiadomienie, ostrzeżenie, błąd itp.) Generowane przez powiązane wyrażenie. Działa podobnie jak operator jednoargumentowy, na przykład ma pierwszeństwo i asocjatywność. Poniżej kilka przykładów:

@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"

Co dokładnie się stanie, jeśli użyjesz niestandardowej procedury obsługi błędów zamiast standardowej procedury obsługi błędów PHP:

Jeśli ustawiłeś niestandardową funkcję obsługi błędów za pomocą funkcji set_error_handler (), nadal będzie ona wywoływana, ale ta niestandardowa procedura obsługi błędów może (i powinna) wywoływać error_reporting (), która zwróci 0, gdy wywołanie, które wywołało błąd, było poprzedzone znakiem @ .

Ilustruje to poniższy przykład kodu:

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"

Program obsługi błędów nie sprawdził, czy @symbol działa. Podręcznik sugeruje, co następuje:

function better_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
    if(error_reporting() !== 0) {
        echo "[better_error_handler]: $errstr";
    }
    // take appropriate action
    return true;
}
Salman A.
źródło
58

Pamiętaj również, że pomimo ukrytych błędów, dowolna niestandardowa procedura obsługi błędów (ustawiona za pomocą set_error_handler) będzie nadal wykonywana!

pseudonim
źródło
34

Jak już niektórzy wcześniej odpowiedzieli: @Operator pomija wszystkie błędy w PHP, w tym powiadomienia, ostrzeżenia, a nawet błędy krytyczne.

ALE: Proszę, naprawdę wcale nie używaj @operatora.

Dlaczego?

Cóż, ponieważ kiedy używasz @operatora do eliminacji błędów, nie masz pojęcia, od czego zacząć, kiedy wystąpi błąd. Miałem już trochę „zabawy” ze starszym kodem, w którym niektórzy programiści @dość często korzystali z operatora. Zwłaszcza w przypadkach takich jak operacje na plikach, połączenia sieciowe itp. Są to wszystkie przypadki, w których wielu programistów zaleca użycie @operatora, ponieważ czasami jest to poza zakresem, gdy wystąpi tutaj błąd (na przykład interfejs API innej firmy może być nieosiągalny itp. ).

Ale po co to nadal go nie używać? Spójrzmy z dwóch perspektyw:

Jako programista: kiedy@jest używany, absolutnie nie mam pojęcia, od czego zacząć. Jeśli istnieją setki, a nawet tysiące wywołań funkcji z@błędem, to może być tak samo. W tym przypadku nie jest możliwe rozsądne debugowanie. A nawet jeśli jest to tylko błąd trzeciej strony - jest w porządku i szybko. ;-) Ponadto lepiej jest dodać wystarczającą ilość szczegółów do dziennika błędów, aby programiści mogli łatwo zdecydować, czy wpis w dzienniku jest czymś, co należy sprawdzić dalej, czy tylko niepowodzeniem innej firmy, które jest poza zakresem dewelopera.

Jako użytkownik: użytkownicy w ogóle nie dbają o przyczynę błędu. Oprogramowanie jest dla nich do pracy, do ukończenia określonego zadania itp. Nie obchodzi ich, czy to wina programisty, czy problem trzeciej strony. Szczególnie dla użytkowników zdecydowanie zalecam rejestrowanie wszystkich błędów, nawet jeśli są poza zakresem. Być może zauważysz, że określony interfejs API jest często offline. Co możesz zrobić? Możesz porozmawiać ze swoim partnerem API, a jeśli nie są w stanie utrzymać stabilności, prawdopodobnie powinieneś poszukać innego partnera.

W skrócie: powinieneś wiedzieć, że istnieje coś takiego @(wiedza jest zawsze dobra), ale po prostu jej nie używaj . Wielu programistów (szczególnie tych debugujących kod od innych) będzie bardzo wdzięcznych.

Andreas
źródło
1
Niektóre ostrzeżenia mogą być niezawodnie tłumione tylko za pomocą @ (np. Fopen (), gdzie każda próba przewidzenia wyniku zależy od warunków wyścigu), jeśli masz kod do obsługi warunku błędu w bardziej uporządkowany sposób, to zwykle @jest właściwe tak, jest to szczególnie przydatne, zwłaszcza jeśli nie wracasz text/html(lub nie jest podobny) do klienta. (może powrót image/pnglub „json”)
Jasen
1
Nie powinieneś tłumić ostrzeżeń - twierdzą, że zrobiłeś coś złego. Nie ma warunków wyścigu, w których nie można poprawnie sprawdzić stanu lub poradzić sobie z nim.
Ryan Rentfro
1
W kilku kodach mam następujące elementy. if( session_status() == PHP_SESSION_NONE ) session_start(); Odziedziczyłem tę starszą aplikację. Są miejsca, w których skrypt instalacyjny jest wywoływany wiele razy, więc muszę przetestować. Jakim ewentualnym problemem byłoby po prostu korzystanie @session_start();?
Stephen R
Jeśli wiesz, co robisz i używasz go oszczędnie / strategicznie, warto go użyć. @$this->stats['device_os'][$date][$creative_id][$device_id][$operating_system]['clicks']++;jest znacznie lepsza niż alternatywa polegająca na sprawdzaniu isset na każdym poziomie i wypełnianiu go, gdy nie jest.
dtbarne
1
Podaj mi dobry powód, dla którego dodanie ponad 12 wierszy kodu i nie dodanie żadnej wartości, ale tylko zmniejszenie czytelności i zwięzłości kodu jest warte innego niż przeczytanie gdzieś, że jest „po prostu brudny” i może możesz zmienić zdanie.
dtbarne
7

Załóżmy, że nie użyliśmy operatora „@”, wówczas nasz kod wyglądałby następująco:

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

A jeśli plik, który próbujemy otworzyć, nie zostanie znaleziony? Wyświetli się komunikat o błędzie.

Aby ukryć komunikat o błędzie, używamy operatora „@”, takiego jak:

$fileHandle = @fopen($fileName, $writeAttributes);
Sujeet Kumar
źródło
To doskonały przykład, dlaczego PHP ma takie @obejście w pierwszej kolejności. Inne języki programowania mają jednolitą obsługę wyjątków, aby poradzić sobie z tego rodzaju scenariuszem stackoverflow.com/questions/1087365
dreftymac
@dreftymac Dokładnie!
Sujeet Kumar
5

Jeśli otwarcie się nie powiedzie, generowany jest błąd poziomu E_WARNING. Możesz użyć @, aby ukryć to ostrzeżenie.

Kishor Singh
źródło
5

@ pomija komunikaty o błędach.

Jest używany w fragmentach kodu, takich jak:

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

Jeśli domena „ http://www.exaple.com ” nie jest dostępna, zostanie wyświetlony błąd, ale @nic nie zostanie pokazane .

fico7489
źródło
1

PHP obsługuje jeden operator kontroli błędów: znak at (@). Po dodaniu do wyrażenia w PHP wszelkie komunikaty o błędach, które mogą zostać wygenerowane przez to wyrażenie, zostaną zignorowane.

Jeśli ustawisz niestandardową funkcję obsługi błędów, set_error_handler()to nadal będzie wywoływana, ale ta niestandardowa procedura obsługi błędów może (i powinna) wywoływać, error_reporting()która zwróci się, 0gdy wywołanie, które wywołało błąd, było poprzedzone znakiem @.

<?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.

?>

Uwaga:-

1) Operator @ działa tylko na wyrażeniach.

2) Prosta zasada: jeśli możesz wziąć wartość czegoś, możesz do tego dołączyć operator @. Na przykład możesz dodać do zmiennych, funkcji i zawierać wywołania, stałe i tak dalej. Nie możesz przygotować go do definicji funkcji lub klas ani struktur warunkowych, takich jak if i foreach i tak dalej.

Ostrzeżenie:-

Obecnie prefiks operatora kontroli błędów „@” wyłącza nawet raportowanie błędów w przypadku błędów krytycznych, które kończą wykonywanie skryptu. Oznacza to między innymi, że jeśli użyjesz „@”, aby ukryć błędy w określonej funkcji i albo nie jest ona dostępna, albo została źle wpisana, skrypt umrze w tym miejscu bez wskazania przyczyny.

Ravi Hirani
źródło
1

Warto dodać tutaj, że podczas korzystania z @ należy pamiętać o kilku wskazówkach, aby zapoznać się z pełnym przeglądem tego postu: http://mstd.eu/index.php/2016/06/30/php- rapid-fire-what-is-the-symbol-used-for-in-php /

  1. Program obsługi błędów jest nadal uruchamiany, nawet jeśli poprzednio wstawiono symbol @, oznacza to po prostu, że ustawiony jest poziom błędu 0, będzie to wymagało odpowiedniej obsługi w niestandardowej procedurze obsługi błędów.

  2. Wcześniejsze dołączenie za pomocą @ ustawi wszystkie błędy w pliku dołączania na poziom błędu 0

twigg
źródło
1

@pomija komunikat o błędzie generowany przez funkcję. fopenzgłasza błąd, gdy plik się nie kończy. @Symbol powoduje wykonanie przejścia do następnego wiersza, nawet jeśli plik nie istnieje. Moja sugestia nie używałaby tego w środowisku lokalnym podczas tworzenia kodu PHP.

Logamurugan Pilavadi Santhanam
źródło