or-operator operadores - El comportamiento del operador o en PHP




asignacion ternario (5)

<?php
$foo = false;
$foo or ($foo = '5');
echo $foo;
?>

Compruebe esto, puede asignar el valor "5" para $foo .

Comparar que or = tiene alta prioridad ... Eso es el hecho ... :)

Estoy tratando de entender el comportamiento de or operador. Por favor vea los ejemplos a continuación:

$e = false || true;
var_dump($e);

La salida es como se esperaba: bool(true);

$f = false or true;
var_dump($f);

La salida es como se esperaba: bool(false) . Entendí esto de una manera que el = tiene una precedencia más alta que el Or , así que es por eso que $f se asigna a false .

Pero el siguiente código funciona bastante diferente de lo que pensaba. Pensé que $foo se asignaría a 5 y luego se compararía a sí mismo. Pero el $foo se asigna solo cuando se establece $foo lo que significa que está comprobando si el $foo está asignado a algo antes, asígnele 5.

$foo or $foo = 5; 

¿Alguien puede explicar por qué esto es así?


De acuerdo con la página web php.net sobre operadores lógicos :

Esta:

$e = false || true;

Actúa así:

$e = (false || true) // If false is true, then $e = false. Otherwise true

Esta:

$f = false or true;

Actuaría así:

($f = false) or true; // $f = false is true, as the assignment succeeded

Esta:

$foo or $foo = 5; 

Actuaría así:

$foo or ($foo = 5) // foo = undefined or foo = 5, so foo = 5

Para el último, indefinido es básicamente falso, por lo tanto, foo es igual a 5.

Además, aquí está el enlace para el orden de precedencia del operador: http://www.php.net/manual/en/language.operators.precedence.php

ACTUALIZAR:

Bien, ahora vayamos al punto principal. Como todos sabemos al usar una consulta captada:

while($row = @mysql_fetch_assoc($result))

Y todos sabemos que los bucles solo se ejecutan en true , por lo tanto $row = @mysql_fetch_assoc($result) devuelve true.

Lo mismo con la pregunta de Daric.

$foo or $foo = 5;

Es básicamente:

$foo or ($foo = 5);

Que es básicamente:

$foo = undefined or ($foo = 5); // $foo = 5 actually returns true

Cual es también

$foo = undefined or true;

Y como he mencionado anteriormente, undefined = false, entonces $ foo = 5 (ya que esa es la declaración verdadera).

Espero que todos puedan entender.


$foo or $foo = 5;

Suppose let say $foo=true or $foo=5;

aquí no se evaluará después de la expresión del operador por lo que la salida será $ foo = 1 Ahora la expresión es

$foo=false or $foo=5;

Aquí evaluará después o como = mayor precedencia así que $foo partir de cuál de los cuales evaluará $foo=5 así que la salida será 5 Pero cuando evaluamos $foo=false or true así que aquí considerará = precedencia más alta para que el el resultado será $foo=false pero la expresión completa se evaluará como verdadera porque false or true vuelve false


Los basicos:

  1. Una expresión de asignación da como resultado el valor asignado.

    Qué significa eso? $foo = 'bar' es una expresión en la que el operador de asignación = asigna un valor. Una expresión siempre devuelve un valor en sí mismo. Al igual que la expresión 1 + 2 da como resultado el valor 3 , la expresión $foo = 'bar' da como resultado el valor 'bar' . Es por eso que esto funciona:

    $foo = $bar = 'baz'; // which is: $foo = ($bar = 'baz');
    
  2. Las operaciones booleanas son operaciones de cortocircuito. Ambas partes no siempre se evalúan si no es necesario. true || false true || false es siempre true general, ya que el operando de la izquierda es true , por lo que toda la expresión debe ser true . false ni siquiera está siendo evaluado aquí.

  3. La precedencia del operador dicta en qué orden las partes de una expresión se agrupan en subexpresiones. Los operadores de mayor precedencia se agrupan con sus operandos antes que los operadores de menor precedencia.

Por lo tanto:

$e = false || true;

false || true false || true se está evaluando, lo que da como resultado el valor true , que se asigna a $e . El || el operador tiene una precedencia mayor que = , por lo tanto false || true false || true se agrupa en una expresión (a diferencia de ($e = false) || true ).

$f = false or true;

Aquí ahora or tiene una precedencia menor que = , lo que significa que la operación de asignación se agrupa en una expresión antes or . Entonces, primero se evalúa la expresión $f = false , cuyo resultado es false (ver arriba). Entonces tiene la expresión simple false or true que se evalúa a continuación y da como resultado true , pero que a nadie le importa.

La evaluación funciona así:

1. $f = false or true;
2. ($f = false) or true;  // precedence grouping
3. false or true;         // evaluation of left side ($f is now false)
4. true;                  // result

Ahora:

$foo or $foo = 5; 

Aquí, de nuevo, $foo = 5 tiene una precedencia más alta y se trata como una expresión. Como ocurre en el lado derecho del operador or , la expresión solo se evalúa si es necesario. Depende de qué $foo sea ​​inicialmente. Si $foo es true , el lado derecho no se evaluará en absoluto, ya que true or ($foo = 5) debe ser true general. Sin embargo, si $foo tiene un valor de falsey inicialmente, se evalúa el lado derecho y 5 se asigna a $foo , lo que da como resultado 5 , que es verdadero, lo que significa que la expresión general es true , lo que a nadie le importa.

1. $foo or $foo = 5;
2. $foo or ($foo = 5);   // precedence grouping
3. false or ($foo = 5);  // evaluation of left side
4. false or 5;           // evaluation of right side ($foo is now 5)
5. true;                 // result

En el ejemplo 3 no modificas la matriz. En todos los demás ejemplos, modifica el contenido o el puntero de matriz interno. Esto es importante cuando se trata de matrices PHP debido a la semántica del operador de asignación.

El operador de asignación para las matrices en PHP funciona más como un clon perezoso. La asignación de una variable a otra que contiene una matriz clonará la matriz, a diferencia de la mayoría de los idiomas. Sin embargo, la clonación real no se realizará a menos que sea necesaria. Esto significa que el clon solo tendrá lugar cuando se modifique cualquiera de las variables (copia en escritura).

Aquí hay un ejemplo:

$a = array(1,2,3);
$b = $a;  // This is lazy cloning of $a. For the time
          // being $a and $b point to the same internal
          // data structure.

$a[] = 3; // Here $a changes, which triggers the actual
          // cloning. From now on, $a and $b are two
          // different data structures. The same would
          // happen if there were a change in $b.

Volviendo a sus casos de prueba, puede imaginar fácilmente que foreach crea algún tipo de iterador con una referencia a la matriz. Esta referencia funciona exactamente como la variable $b en mi ejemplo. Sin embargo, el iterador junto con la referencia en vivo solo durante el bucle y luego, ambos se descartan. Ahora puede ver que, en todos los casos, excepto 3, la matriz se modifica durante el bucle, mientras esta referencia adicional está activa. ¡Esto activa un clon, y eso explica lo que está pasando aquí!

Este es un excelente artículo sobre otro efecto secundario de este comportamiento de copia en escritura: El operador PHP ternario: ¿Rápido o no?





php or-operator