Na czym polega użycie symbolu @ w PHP?

Widziałem użycie @ przed niektórymi funkcjami, jak poniżej:

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

Jaki jest użytek z tego symbolu?

Author: Peter Mortensen, 2009-06-23

11 answers

Tłumi komunikaty o błędach-zobacz operatory kontroli Błędów w podręczniku PHP.

 573
Author: RichieHindle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-28 08:16:06

Tłumi błędy.

Zobacz operatory kontroli Błędów w instrukcji:

PHP obsługuje jeden operator kontroli błędów: znak at (@). Gdy poprzedzone wyrażeniem w PHP, wszelkie komunikaty o błędach, które mogą być generowane przez to wyrażenie, będą ignorowane.

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

 410
Author: Aiden Bell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-07 15:48:40

Symbolem @ jest kontrola błędów operator (znany również jako operator" silence "lub" shut-up"). Powoduje to, że PHP eliminuje wszelkie komunikaty o błędach (powiadomienie, Ostrzeżenie, fatal, itp.) generowane przez powiązane wyrażenie. Działa podobnie jak operator jednoargumentowy, na przykład ma pierwszeństwo i asocjację. 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 niestandardowego programu obsługi błędów zamiast standardowego programu obsługi błędów PHP:

Jeśli ustawić niestandardową funkcję obsługi błędów z set_error_handler() wtedy nadal zostanie wywołana, ale ten zwyczaj obsługa błędów może (i powinna) wywołać error_reporting (), co spowoduje zwraca 0, gdy wywołanie wywołujące 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"

Obsługa błędów nie sprawdzała, 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;
}
 199
Author: Salman A,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-03 10:50:44

Zauważ również, że pomimo ukrycia błędów, każdy niestandardowy program obsługi błędów (ustawiony przez set_error_handler) nadal będzie wykonywany!

 55
Author: nickf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-11 14:48:24

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

Ale: proszę, naprawdę nie używaj w ogóle operatora @.

Dlaczego?

Cóż, ponieważ kiedy używasz operatora @ do supresji błędów, nie masz pojęcia, od czego zacząć, gdy wystąpi błąd. Miałem już trochę "zabawy" ze starszym kodem, gdzie niektórzy programiści używali @ operator dość często. Szczególnie 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 błąd (na przykład API 3rdparty może być nieosiągalne, itp.).

Ale jaki jest sens, aby nadal go nie używać? Spójrzmy z dwóch perspektyw:

jako deweloper: kiedy @ jest używany, nie mam absolutnie pojęcia, od czego zacząć. Jeśli istnieją setki, a nawet tysiące wywołań funkcji z @ błąd może być jak everyhwere. W tym przypadku nie jest możliwe rozsądne debugowanie. A nawet jeśli jest to tylko błąd 3rdparty - to jest w porządku i szybko się skończy. ;-) Co więcej, lepiej dodać wystarczająco dużo szczegółów do dziennika błędów, aby programiści mogli łatwo zdecydować, czy wpis dziennika jest czymś, co należy sprawdzić dalej, czy jest to tylko awaria 3rdparty, która jest poza zakresem dewelopera.

jako użytkownik: użytkownicy w ogóle nie dbają o to, jaki jest powód błędu, czy nie. Oprogramowanie jest tam dla nich do pracy, do ukończenia określonego zadania, itp. Nie obchodzi ich, czy to wina dewelopera, czy problem 3rdparty. Szczególnie dla użytkowników, zdecydowanie polecam do logowania wszystkich błędów, nawet jeśli są one poza zakresem. Być może zauważysz, że określone API jest często offline. Co możesz zrobić? Możesz porozmawiać ze swoim partnerem API, a jeśli nie jest w stanie utrzymać jego stabilności, prawdopodobnie powinieneś poszukać dla innego partnera.

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

 27
Author: Andreas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-27 14:35:44

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

 5
Author: Kishor Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-12 10:41:56

Załóżmy, że nie użyliśmy operatora"@", wtedy nasz kod będzie wyglądał tak:

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

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

Aby stłumić komunikat o błędzie używamy operatora " @ " jak:

$fileHandle = @fopen($fileName, $writeAttributes);
 5
Author: Sujeet Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-06 11:36:40

@ tłumi komunikaty o błędach.

Jest używany w fragmentach kodu takich jak:

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

If domain " http://www.exaple.com " nie jest dostępna, zostanie wyświetlony błąd, ale z @ nic nie jest pokazywane.

 2
Author: fico7489,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-18 11:21:41

PHP obsługuje jeden operator kontroli błędów: znak at (@). Gdy poprzedzone wyrażeniem w PHP, wszelkie komunikaty o błędach, które mogą być generowane przez to wyrażenie, będą ignorowane.

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

<?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 jest taka: jeśli możesz wziąć wartość czegoś, możesz poprzedzić operator @ do tego. Na przykład, można poprzedzić go zmiennymi, funkcjami i zawierać wywołania, stałe i tak dalej. Nie można poprzedzić go definicjami funkcji lub klas, strukturami warunkowymi, takimi jak if i foreach, itd.

Ostrzeżenie:-

Obecnie prefiks operatora kontroli błędów " @ " wyłączy nawet zgłaszanie błędów krytycznych, które zakończą działanie skryptu egzekucja. Między innymi oznacza to, że jeśli użyjesz " @ " do eliminuje błędy z określonej funkcji i albo nie jest dostępna lub został błędnie wpisany, skrypt umrze tam bez wskazanie, dlaczego.

 1
Author: Ravi Hirani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-17 08:50:45

Może warto dodać tutaj kilka wskazówek, gdy używasz @ powinieneś być świadomy, aby uzyskać pełny przegląd tego posta: 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 z symbolem@, oznacza to tylko, że ustawiony jest poziom błędu 0, który będzie musiał być odpowiednio obsługiwany w niestandardowym programie obsługi błędów.

  2. Prepending a include with @ will set wszystkie błędy w pliku dołączonym do poziomu błędu 0

 1
Author: twigg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-30 14:35:28

@ wyłącza komunikat o błędzie wyświetlany przez funkcję. fopen wyświetla błąd, gdy plik nie kończy się. @ symbol powoduje, że wykonanie przechodzi do następnej linii, nawet jeśli plik nie istnieje. Moją sugestią byłoby nie używać tego w swoim lokalnym środowisku podczas tworzenia kodu PHP.

 0
Author: Logamurugan Pilavadi Santhanam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-18 11:22:43