¿Para qué sirve el símbolo @ en PHP?

577

He visto usos de @ciertas funciones, como las siguientes:

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

¿Para qué sirve este símbolo?

sv_in
fuente
3
Tanto RichieHindle como Aiden Bell dieron la respuesta correcta, pero como solo puedo establecer una respuesta como aceptada, elegiré la primera. Lo siento Aiden
sv_in
1
La supresión de errores (aunque agradable) podría causar errores en el
futuro

Respuestas:

636

Suprime los mensajes de error; consulte Operadores de control de errores en el manual de PHP.

RichieHindle
fuente
46
¡Fue un empate un poco rápido!
Aiden Bell
66
Si; ¡hasta el segundo! Tenía que comprobar la respuesta-id es para ver quién llegó en primer lugar :)
Sampson
3
Tuve tiempo de corregir mi ortografía de supresión después de publicar ... y maldito sea por mejorar con un enlace al mismo tiempo que se desata : P
Aiden Bell
1
Característica genial. Hace isset()innecesario el uso de 's para evitar undefined offseterrores.
WM
470

Suprime errores.

Ver Operadores de control de errores en el manual:

PHP admite un operador de control de errores: el signo at (@). Cuando se antepone a una expresión en PHP, cualquier mensaje de error que pueda generar esa expresión será ignorado.

Si ha configurado una función de controlador de errores personalizada con set_error_handler () , se le seguirá llamando, pero este controlador de errores personalizado puede (y debería) llamar a error_reporting () que devolverá 0 cuando la llamada que activó el error fue precedida por una @ ...

Aiden Bell
fuente
157
votó solo porque la otra respuesta es obtener todo el amor.
ajacian81
10
19 detrás ... vamos gente vamos a vencer a RichieHindle: P
Aiden Bell
Esta respuesta fue la primera (en contexto con quién la respondió primero).
Mohd Abdul Mujib el
227

El @símbolo es el operador de control de errores (también conocido como el operador "silencio" o "apagado"). Hace que PHP suprima cualquier mensaje de error (aviso, advertencia, fatal, etc.) generado por la expresión asociada. Funciona igual que un operador unario, por ejemplo, tiene prioridad y asociatividad. A continuación hay algunos ejemplos:

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

Qué sucede exactamente si usa un controlador de errores personalizado en lugar del controlador de errores estándar de PHP:

Si ha configurado una función de controlador de errores personalizada con set_error_handler (), se le seguirá llamando, pero este controlador de errores personalizado puede (y debería) llamar a error_reporting () que devolverá 0 cuando la llamada que activó el error fue precedida por una @ .

Esto se ilustra en el siguiente ejemplo de código:

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"

El controlador de errores no verificó si el @símbolo estaba vigente. El manual sugiere lo siguiente:

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
fuente
58

También tenga en cuenta que a pesar de que los errores están ocultos, ¡cualquier controlador de errores personalizado (configurado con set_error_handler) aún se ejecutará!

nickf
fuente
34

Como ya algunos respondieron antes: el @operador suprime todos los errores en PHP, incluidos avisos, advertencias e incluso errores críticos.

PERO: Por favor, realmente no use el @operador en absoluto.

¿Por qué?

Bueno, porque cuando usa el @operador para la supresión de errores, no tiene idea de dónde comenzar cuando se produce un error. Ya me divertí un poco con el código heredado donde algunos desarrolladores usaban el @operador con bastante frecuencia. Especialmente en casos como operaciones de archivos, llamadas de red, etc. Esos son todos los casos en que muchos desarrolladores recomiendan el uso del @operador, ya que esto a veces está fuera de alcance cuando ocurre un error aquí (por ejemplo, una API de terceros podría ser inalcanzable, etc. )

¿Pero cuál es el punto de no usarlo? Echemos un vistazo desde dos perspectivas:

Como desarrollador: cuando@se usa, no tengo ni idea de por dónde empezar. Si hay cientos o incluso miles de llamadas a funciones con@el error, podría ser como todo el mundo. No es posible una depuración razonable en este caso. E incluso si es solo un error de un tercero, entonces está bien y has terminado rápido. ;-) Además, es mejor agregar suficientes detalles al registro de errores, para que los desarrolladores puedan decidir fácilmente si una entrada de registro es algo que debe verificarse más a fondo o si es solo una falla de terceros que está fuera del alcance del desarrollador.

Como usuario: a los usuarios no les importa en absoluto cuál es el motivo de un error o no. El software está ahí para que trabajen, para finalizar una tarea específica, etc. No les importa si es culpa del desarrollador o un problema de un tercero. Especialmente para los usuarios, recomiendo registrar todos los errores, incluso si están fuera de alcance. Tal vez notará que una API específica está fuera de línea con frecuencia. ¿Qué puedes hacer? Puede hablar con su socio API y si no pueden mantenerlo estable, probablemente debería buscar otro socio.

En resumen: debe saber que existe algo como @(el conocimiento siempre es bueno), pero simplemente no lo use . Muchos desarrolladores (especialmente aquellos que depuran el código de otros) estarán muy agradecidos.

Andreas
fuente
1
Algunas advertencias solo se pueden suprimir de manera confiable usando @ (por ejemplo, fopen (), donde cualquier intento de predecir el resultado está sujeto a una condición de carrera), si tiene un código para manejar la condición de error de una manera más ordenada, usuig @es lo correcto. hacer, esto es especialmente útil, especialmente si no está volviendo text/html(o similar) al cliente. (tal vez regresando image/pngo "json")
Jasen
1
No deberías suprimir las advertencias: dicen que has hecho algo mal. No existe una condición de carrera en la que no pueda verificar o manejar adecuadamente el estado.
Ryan Rentfro
1
Tengo lo siguiente en mi código en algunos lugares. if( session_status() == PHP_SESSION_NONE ) session_start(); Es una aplicación heredada que heredé, y hay lugares donde el script de configuración se llama varias veces, por lo que tengo que probarlo. ¿Qué problema, si lo hay, habría en simplemente usar @session_start();?
Stephen R
Si sabe lo que está haciendo y lo usa con moderación / estrategia, vale la pena usarlo. @$this->stats['device_os'][$date][$creative_id][$device_id][$operating_system]['clicks']++;es mucho mejor que la alternativa de tener controles de activos en cada nivel y completarlo cuando no lo es.
dtbarne
1
Dame una buena razón por la que valga la pena agregar más de 12 líneas de código y no agregar valor, pero solo reducir la legibilidad y la brevedad del código, aparte de lo que leíste en algún momento que está "completamente sucio" y tal vez puedas cambiar de opinión.
dtbarne
7

Supongamos que no hemos usado el operador "@", entonces nuestro código se vería así:

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

¿Y si no se encuentra el archivo que estamos intentando abrir? Mostrará un mensaje de error.

Para suprimir el mensaje de error, estamos utilizando el operador "@" como:

$fileHandle = @fopen($fileName, $writeAttributes);
Sujeet Kumar
fuente
Este es un ejemplo perfecto de por qué PHP tiene este tipo de @solución en primer lugar. Otros lenguajes de programación tienen un manejo uniforme de excepciones para lidiar con este tipo de escenario stackoverflow.com/questions/1087365
dreftymac
@dreftymac ¡Exactamente!
Sujeet Kumar el
5

Si falla la apertura, se genera un error de nivel E_WARNING. Puede usar @ para suprimir esta advertencia.

Kishor Singh
fuente
5

@ suprime los mensajes de error.

Se usa en fragmentos de código como:

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

Si el dominio " http://www.exaple.com " no es accesible, se mostrará un error, pero @no se mostrará nada.

fico7489
fuente
1

PHP admite un operador de control de errores: el signo at (@). Cuando se antepone a una expresión en PHP, cualquier mensaje de error que pueda generar esa expresión será ignorado.

Si ha configurado una función de controlador de errores personalizada, set_error_handler()entonces todavía se llamará, pero este controlador de errores personalizado puede (y debería) llamar, error_reporting()lo que regresará 0cuando la llamada que activó el error fue precedida por un @.

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

?>

Nota:-

1) El @ -operator solo funciona en expresiones.

2) Una regla general simple es: si puede tomar el valor de algo, puede anteponerle el operador @. Por ejemplo, puede anteponerlo a variables, funciones e incluir llamadas, constantes, etc. No puede anteponerlo a definiciones de funciones o clases, o estructuras condicionales como if y foreach, etc.

Advertencia:-

Actualmente, el prefijo del operador de control de errores "@" incluso deshabilitará los informes de errores para errores críticos que terminarán la ejecución del script. Entre otras cosas, esto significa que si usa "@" para suprimir errores de una determinada función y no está disponible o ha sido mal escrito, el script morirá allí sin ninguna indicación de por qué.

Ravi Hirani
fuente
1

Puede valer la pena agregar aquí que hay algunos consejos al usar la @ que debe tener en cuenta, para ver un resumen completo de esta publicación: http://mstd.eu/index.php/2016/06/30/php- rapid-fire-what-is-the-symbol-used-for-in-php /

  1. El controlador de errores todavía se activa incluso con el símbolo @ antepuesto, solo significa que se establece un nivel de error de 0, esto tendrá que manejarse adecuadamente en un controlador de errores personalizado.

  2. Anteponer una inclusión con @ establecerá todos los errores en el archivo de inclusión a un nivel de error de 0

ramita
fuente
1

@suprime el mensaje de error lanzado por la función. fopenarroja un error cuando el archivo no sale. @El símbolo hace que la ejecución se mueva a la siguiente línea, incluso si el archivo no existe. Mi sugerencia sería no usar esto en su entorno local cuando desarrolle un código PHP.

Logamurugan Pilavadi Santhanam
fuente