Operadores lógicos, || ¿o o?

104

Recuerdo haber leído hace un tiempo sobre los operadores lógicos que, en el caso de OR, usar ||era mejor que or(o viceversa).

Solo tenía que usar esto en mi proyecto cuando volví a mí, pero no puedo recordar qué operador se recomendó o si era cierto.

¿Cuál es mejor y por qué?

SuPronunciado
fuente

Respuestas:

139

No hay "mejor" pero el más común es ||. Tienen diferente precedencia y ||funcionarían como cabría esperar normalmente.

Ver también: Operadores lógicos ( el siguiente ejemplo se toma de allí ):

// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;

// The constant false is assigned to $f and then true is ignored
// Acts like: (($f = false) or true)
$f = false or true;
Felix Kling
fuente
11
y $e = true || $x = 'foo'no se definirá $xdebido a un cortocircuito, no debido a una mayor precedencia.
Matt Kieran
1
También vale la pena señalar que estos siempre devuelven un valor booleano, a diferencia de muchos otros lenguajes donde devuelven el último valor verificado. Entonces, en PHP (27 || 0) devuelve verdadero , no 27 .
TextGeek
@TextGeek, "estos"? 27 or 0regresa 27por mi.
Jānis Elmeris
@ Jānis Elmeris - tienes razón, debería haberme referido solo al "||" caso.
TextGeek
2
@TextGeek, en realidad, tiene razón, eso también ordevuelve booleano. Su precedencia es tan baja que a veces parece que hace otra cosa. :) print 27 or 0se imprimiría 27porque orsucede después print 27 . Por cierto, echono se engaña - echo 27 or 0saldría 1.
Jānis Elmeris
43

Se utilizan para diferentes propósitos y de hecho tienen diferentes precedencias de operadores. Los operadores &&y ||están pensados ​​para condiciones booleanas, mientras que andy orestán pensados ​​para controlar el flujo.

Por ejemplo, la siguiente es una condición booleana:

if ($foo == $bar && $baz != $quxx) {

Esto difiere del flujo de control:

doSomething() or die();
Matthew Ratzloff
fuente
die()se llamará a la función si doSomething()volverá falseo null? ¿Y si doSomething()regresa trueo nada?
giannis christofakis
5
doSomething()se evalúa como booleano. Si devuelve un valor que PHP considera verdadero ( true, una cadena no vacía, etc.), no llamará die().
Matthew Ratzloff
23

La diferencia entre respectivamente || y OR y && y AND es la precedencia del operador :

$bool = FALSE || TRUE;

  • interpretado como ($bool = (FALSE || TRUE))
  • valor de $boolesTRUE

$bool = FALSE OR TRUE;

  • interpretado como (($bool = FALSE) OR TRUE)
  • valor de $boolesFALSE

$bool = TRUE && FALSE;

  • interpretado como ($bool = (TRUE && FALSE))
  • valor de $boolesFALSE

$bool = TRUE AND FALSE;

  • interpretado como (($bool = TRUE) AND FALSE)
  • valor de $boolesTRUE
John Slegers
fuente
5

Fuente: http://wallstreetdeveloper.com/php-logical-operators/

Aquí hay un código de muestra para trabajar con operadores lógicos:

<html>

<head>
    <title>Logical</title>
</head>

<body>
    <?php
        $a = 10;
        $b = 20;
        if ($a>$b)
        {
            echo " A is Greater";
        }
        elseif ($a<$b)
        {
            echo " A is lesser";
        }
        else
        {
             echo "A and B are equal";
        }
    ?>
    <?php
        $c = 30;
        $d = 40;
        //if (($a<$c) AND ($b<$d))
        if (($a<$c) && ($b<$d))
        {
            echo "A and B are larger";
        }
        if (isset($d))
            $d = 100;
        echo $d;
        unset($d);
    ?>
    <?php
        $var1 = 2;
        switch($var1)
        {
            case 1:  echo "var1 is 1";
                     break;
            case 2:  echo "var1 is 2";
                     break;
            case 3:  echo "var1 is 3";
                     break;
            default: echo "var1 is unknown";
        }
    ?>
</body>
</html>
improgramador
fuente
El vínculo está roto.
Peter Mortensen
2

Sé que es un tema antiguo, pero aún así. Acabo de encontrar el problema en el código que estoy depurando en el trabajo y tal vez alguien pueda tener un problema similar ...

Digamos que el código se ve así:

$positions = $this->positions() || [];

Usted esperaría (como está acostumbrado a, por ejemplo, javascript) que cuando $ this-> posiciones () devuelve falso o nulo, $ posiciones es una matriz vacía. Pero no lo es. El valor es VERDADERO o FALSO depende de lo que devuelva $ this-> posiciones ().

Si necesita obtener el valor de $ this-> posiciones () o una matriz vacía, debe usar:

$positions = $this->positions() or [];

EDITAR:

El ejemplo anterior no funciona como se esperaba pero la verdad es que ||y orno es lo mismo ... Prueba esto:

<?php

function returnEmpty()
{
  //return "string";
  //return [1];
  return null;
}

$first = returnEmpty() || [];
$second = returnEmpty() or [];
$third = returnEmpty() ?: [];

var_dump($first);
var_dump($second);
var_dump($third);
echo "\n";

Este es el resultado:

bool(false)
NULL
array(0) {
}

Entonces, en realidad, la tercera opción ?:es la solución correcta cuando desea establecer un valor devuelto o una matriz vacía.

$positions = $this->positions() ?: [];

Probado con PHP 7.2.1

Zdeněk
fuente
es una respuesta incorrecta, el segundo ejemplo funciona exactamente como el primero
WayFarer
@WayFarer bueno, no es correcto (hay un problema) pero usted también se equivoca (|| y OR no es lo mismo) - vea mi edición
Zdeněk
derecha, operadores || y 'o' tienen una prioridad diferente, por lo que su segundo ejemplo funciona como: (($ second = returnEmpty ()) o []); Entonces, la respuesta a la pregunta original sería || es mejor,
úselo
1
$positions = $this->positions() ?? [];es probablemente lo que quieres.
obispo
0

No creo que uno sea intrínsecamente mejor que otro, pero sugeriría seguir con || porque es el predeterminado en la mayoría de los idiomas.

EDITAR: Como otros han señalado, de hecho existe una diferencia entre los dos.

exahex
fuente
0

No hay nada malo o mejor, solo depende de la precedencia de los operadores. Dado que ||tiene mayor precedencia que or, por lo que ||se usa principalmente.

Nishu Tayal
fuente
-3

Algunos lenguajes usan cortocircuito y otros usan evaluación booleana completa (si lo sabe, esto es similar a la directiva $B en Pascal).

Explicaciones:

function A(){
    ...Do something..
    return true;
}

function B(){
    ...Do something..
    return true;
}

if ( A() OR B() ) { .....

En este ejemplo, la función B()nunca se ejecutará. Dado que la función A()devuelve VERDADERO, el resultado de la instrucción OR se conoce a partir de la primera parte sin que sea necesario evaluar la segunda parte de la expresión.

Sin embargo ( A() || B() ), la segunda parte siempre se evalúa independientemente del valor de la primera.

Para una programación optimizada, siempre debe usar la ORque sea más rápida (excepto en el caso en que la primera parte regrese falsey la segunda parte realmente necesite ser evaluada).

janhsh
fuente
Esta no es '¡La mejor respuesta!'. Desplácese hacia arriba y tome la respuesta más votada para obtener una buena explicación. Con el ||, Bno se llamará. Ambos operadores hacen exactamente lo mismo, excepto que la precedencia es diferente.
bzeaman
"siempre debes usar OR, que es más rápido" Hmm, me pregunto si esto es cierto ... así que verifiquemos que: 3v4l.org/5QSAA/vld#tabs 3v4l.org/PdjJP/vld#tabs El número de códigos de operación es el mismo. Así que no importa el rendimiento.
Jens A. Koch