2010-07-21 10 views
17

menudo en PHP, veo:El uso de 'or die()' para detenerse en los errores en PHP

$result = mysql_query($query) or die(); 

Viniendo de pitón, sé por qué esto debería funcionar, porque or devuelve el primer valor si se trata de verdadero en un contexto booleano, y el segundo valor de lo contrario (vea this).

Pero cuando trato de la técnica anterior en PHP en otro contexto, por ejemplo, algo como:

$name = "John Doe"; 
echo $name or "Anonymous"; 

El or no devuelve el primer valor ("John Doe"), devuelve 1.

¿Por qué funciona esto en el caso de resultado mysql_query(), pero no en otros casos? ¿Es malo utilizarlo en un caso mysql_query() (ignore el hecho de que no estoy devolviendo un error útil al usuario)?

Respuesta

33

En PHP, la asignación de variables (el signo igual) y las funciones tienen prioridad sobre el operador or. Eso significa que una función se ejecuta primero, luego el valor de retorno de la función se usa en la comparación or. A su vez, cuando utiliza dos valores/variables junto con un operador or, compara los dos valores primero y luego devuelve un valor booleano.

Por lo tanto, el orden de evaluación en este ejemplo es:

$result = mysql_query($query) or die(); 
  1. mysql_query($query)
    devuelve un conjunto de resultados para consultas DQL como SELECT, o un valor booleano para DDL, DML o consultas de DCL como CREATE, DROP, INSERT, UPDATE, DELETE y ALTER.

  2. $result = mysql_query($query)
    El resultado de esta ejecución de la consulta se asigna a la variable $result.

  3. $result /* = ... */ or die();
    Si es o bien un conjunto de resultados o true, se considera verdadero (también conocido como "Truthy") por lo que la condición se cumple or y la declaración termina aquí. De lo contrario, la secuencia de comandos sería die() en su lugar.


echo es una construcción del lenguaje y, por tanto, en realidad no devolver un valor, por lo que no se ejecuta como una función antes de realizar la comparación or.

Como $name or "Anonymous" siempre es cierto porque la cadena "Anonymous" no está vacío y, por tanto Truthy, la echo convierte implícitamente true a 1, de ahí que la salida.

El orden de evaluación en este ejemplo es:

$name = "John Doe"; 
echo $name or "Anonymous"; 
  1. $name = "John Doe";
    Bastante sencillo - asigna la cadena John Doe a $name.

  2. $name or "Anonymous"
    PHP descubre que contiene la cadena $nameJohn Doe, así que lo que termina siendo evaluado es el siguiente:

  3. "John Doe" or "Anonymous"
    Desde por lo menos una cadena es no vacío aquí, se considera verdad y la condición está satisfecha. Esta evaluación luego devuelve true.

  4. echo true /* $name or... */;
    Convierte true a 1 e imprime el número 1.

+2

+1 Gran explicación. – karim79

+3

+1 gran palabra, "verdad" –

+0

Entonces, supongo que esto funcionará con las funciones de impresión como 'printf', ¿o es el mismo problema, porque produce resultados? Es una función así que debería funcionar, ¿verdad? –

0

Eso es porque echo no es una función, es una construcción de lenguaje. Se imita para ser una función, pero realmente no lo es :)

Nunca usaría die() así, es un poco áspero. Debe manejar sus errores de forma adecuada, no simplemente rescatar.

+0

Dije "ignorar el hecho de que no estoy devolviendo un error útil al usuario", eso no es parte de la pregunta.Te has perdido todo el problema con esta respuesta. No importa que el eco del clima sea una función o no. 'echo (falso o verdadero);' o 'printf (falso o verdadero);' debe ser igual que '$ a = (falso o verdadero); echo $ a; ' – rjmunro

+0

@rjmunro: El primer párrafo (trata de) responder a su pregunta. ¿Qué debe 'echo $ name o "John Doe"; 'do? '(echo $ name) o" John Doe "' OR 'echo ($ nombre o" John Doe ")'? Esa es una cuestión importante. Y, por lo tanto, es importante si es una función (con un valor de retorno) o una construcción de lenguaje (sin valor de retorno). –

2

¿Por qué or devolver algo? or es un operador booleano normal. $a or $b es true si $a o $b evalúa a true y false si no.

La diferencia entre || y or es, que tiene una or precedance operador más bajo, incluso inferior a =.Esta es la razón por

$result = mysql_query($query) or die(); 

es igual que

($result = mysql_query($query)) or (die()); 

mientras que

$result = mysql_query($query) || die(); 

es igual que

$result = (mysql_query($query) || die()); 

En su caso

echo $name or "Anonymous"; 

obtiene

(echo $name) or ("Anonymous"); 

Lo que se busca es, probablemente, el operador ternario:

echo $name ?: 'Anonymous'; 

Lo anterior va a funcionar a partir de PHP 5.3, si sólo tiene PHP 5.2 uso:

echo $name ? $name : 'Anonymous'; 
1

PHP hace algo a menudo llamado "malabarismo tipo". En otras palabras: PHP transforma el tipo de cualquier valor para el caso de uso actual. Dado que Strings se transformará en valores "verdaderos", su expresión devuelve verdadero. Pero echo quiere imprimir una expresión de cadena y transforma "verdadero" a 1. Un poco molesto en algunos casos, pero si lo sabe, también sabe cómo manejar;)

mira esto, por cierto: http://php.net/manual/en/types.comparisons.php

1

la cláusula or se evalúa primero y devuelve un booleano que arroja las salidas echo. Si desea texto de salida que necesita un if/else como:

echo ($name ? $name : 'Anonymous'); 
+4

o si está ejecutando PHP 5.3+, 'echo $ name?:" Anónimo ";' – nickf

2

La razón de hecho me ocurrió poco después de hacer la pregunta. Se trata de la precedencia del operador. El = sucede antes de la or, por lo que:

$result = mysql_query($query) or die(); 

es equivalente a:

($result = mysql_query($query)) or die(); 

no:

$result = (mysql_query($query) or die()); 

como lo sería en Python. Así que esto:

$a = false or true; 

establecerá $a a falso, no es cierto, que está obligado a cogerme a cabo en algún momento en el futuro.

0

Si desea replicar ese comportamiento Y la salida a la pantalla/navegador, necesita una función que devolverá algo que no sea VERDADERO. printf() puede hacer eso por usted.

echo microtime."&lt;br&gt;";< 
$str = ""; 
printf("%s",$str) or die(); 
echo "&lt;br&gt;".microtime(); 

Si $ cadena está vacía, nula, o falsa de la matriz será llamado(), de lo contrario, el script se termina la ejecución.

Cuestiones relacionadas