operadores - php operador logico or
Malabarismo de tipos y(estricto) mayor/menor que las comparaciones en PHP (3)
Después de corregir la segunda parte de su pregunta, dejo la respuesta a esa parte a los demás. Solo quiero dar la respuesta más sorprendente a la primera parte de su pregunta, es decir, si hay un ejemplo de que los operadores <
y >
son intransitivos. Aquí está.
Todos estos son true
:
"10" < "1a"
"1a" < "2"
"10" > "2"
Si <
fuera transitivo ( $a < $b
∧ $b < $c
⇒ $a < $c
), la última línea sería
"10" < "2"
pero PHP intenta ser amable (?!) e interpreta las cadenas como números siempre que sea posible.
Resulta que, debido a la intransitividad anterior, sort()
puede ordenar los mismos elementos en un orden diferente dependiendo de su orden de entrada, incluso cuando no hay dos elementos ==
(y ningún elemento es NAN). Señalé esto en un comentario para ordenar () , cuya esencia es:
sort(array("10", "1a", "2" )) => array("10", "1a", "2" )
sort(array("10", "2", "1a")) => array("1a", "2", "10")
sort(array("1a", "10", "2" )) => array("2", "10", "1a")
sort(array("1a", "2", "10")) => array("1a", "2", "10")
sort(array("2", "10", "1a")) => array("2", "10", "1a")
sort(array("2", "1a", "10")) => array("10", "1a", "2" )
PHP es famoso por su tipo de malabares. Debo admitir que me desconcierta, y estoy teniendo dificultades para descubrir elementos básicos / lógicos básicos en las comparaciones.
Por ejemplo: si $a > $b
es verdadero y $b > $c
es verdadero, ¿debe significar que $a > $c
es verdadero?
Siguiendo la lógica básica, yo diría que sí, pero estoy tan perplejo que realmente no confío en PHP en esto. Tal vez alguien puede dar un ejemplo donde este no es el caso?
También me pregunto con los estrictos operadores menor que y estrictos (ya que su significado se describe estrictamente, lo que solo sabía en el pasado de las comparaciones de igualdad) si hace alguna diferencia si los operandos izquierdos y derechos se intercambian con valores estrictamente desiguales:
# Precondition:
if ($a === $b) {
throw new Exception(
''Both are strictly equal - can not compare strictly for greater or smaller''
);
}
($a > $b) !== ($b > $a)
Para la mayoría de las combinaciones de comparación de tipo, estos operadores de comparación mayor / menor no están documentados, por lo que leer el manual no fue realmente útil en este caso.
Los operadores de comparación de PHP se desvían de las definiciones científico-informáticas de varias maneras:
Para constituir una relación de equivalencia ==
tiene que ser reflexivo, simétrico y transitivo:
El operador PHP
==
no es reflexivo , es decir,$a == $a
no siempre es cierto:var_dump(NAN == NAN); // bool(false)
Nota: El hecho de que cualquier comparación que involucre
NAN
sea siemprefalse
no es específica de PHP. Es obligatorio según el estándar IEEE 754 para aritmética de coma flotante ( más información ).El operador de PHP
==
es simétrico , es decir,$a == $b
y$b == $a
son siempre los mismos.El operador PHP
==
no es transitivo , es decir, de$a == $b
y$b == $c
no sigue$a == $c
:var_dump(true == "a"); // bool(true) var_dump("a" == 0); // bool(true) var_dump(true == 0); // bool(false)
Para constituir un orden parcial <=
/ >=
tiene que ser reflexivo, antisimétrico y transitivo:
El operador
<=
operador de PHP no es reflexivo , es decir,$a <= $a
no siempre es verdadero (Ejemplo igual que para==
).El
<=
operador de PHP no es antisimétrico , es decir, de$a <= $b
y$b <= $a
no sigue$a == $b
:var_dump(NAN <= "foo"); // bool(true) var_dump("foo" <= NAN); // bool(true) var_dump(NAN == "foo"); // bool(false)
El
<=
operador de PHP no es transitivo , es decir, de$a <= $b
y$b <= $c
no sigue$a <= $c
(Ejemplo igual que para==
).Extra: el operador
<=
operador de PHP no es total , es decir, tanto$a <= $b
como$b <= $a
pueden ser falsos:var_dump(new stdClass <= new DateTime); // bool(false) var_dump(new DateTime <= new stdClass); // bool(false)
Para constituir un orden parcial estricto, <
/ >
tiene que ser irreflexivo, asimétrico y transitivo:
El operador
<
de PHP es irreflexivo , es decir,$a < $a
nunca es verdadero. Tenga en cuenta que esto es cierto solo a partir de PHP 5.4 . AnteriormenteINF < INF
evaluado comotrue
.El operador
<
de PHP no es asimétrico , es decir, ¡de$a < $b
no sigue!($b < $a)
(Ejemplo igual que para<=
no ser antisimétrico).El operador
<
de PHP no es transitivo , es decir, de$a < $b
y$b < $c
no sigue$a < $c
:var_dump(-INF < 0); // bool(true) var_dump(0 < TRUE); // bool(true) var_dump(-INF < TRUE); // bool(false)
Extra: el
<
operador de PHP no es tricotómico , es decir, todos$a < $b
,$b < $a
y$a == $b
pueden ser falsos (Ejemplo igual que para<=
no es total).Extra: el
<
operador de PHP puede ser circular , es decir, es posible que$a < $b
,$b < $c
y$c < $a
:var_dump(INF < []); // bool(true) var_dump([] < new stdClass); // bool(true) var_dump(new stdClass < INF); // bool(true)
Nota: El ejemplo anterior arroja un aviso de "Objeto de clase stdClass no se puede convertir a doble".
Puede encontrar algunos buenos gráficos para los operadores de comparación de PHP en PHP Sadness 52 - Operadores de comparación .
Como última nota, quiero señalar que hay dos iguales que PHP garantiza (a diferencia de casi todo lo demás). Estos dos siempre se sostienen, simplemente porque el compilador se reduce uno al otro:
($a > $b) == ($b < $a)
($a >= $b) == ($b <= $a)
No hay operadores de comparación estrictamente idénticos ( >==
o <==
) en PHP (por PHP 5.6.14 al menos) , pero hay algunas maneras de aplicar una verificación de tipo estricta antes de comprobar Mayor / Menor:
- Verifique ambos tipos de variables con
if (gettype($a) === gettype($b))
- Fuerza tu tipo de yeso necesario, por ej.
if ((string)$a === (string)$b)
- Forza tu tipo de malabarismo necesario, por ejemplo.
if (($a . '''') === ($b . ''''))
Tenga en cuenta que:
- La precisión del punto flotante es limitada
-
INF
yNAN
son de tipofloat
bajo ieee754 - Algún Infinito equivale a algún otro Infinito (desde PHP 5.4)
- La notación científica
e
siempre es de tipofloat
, y nuncainteger
incluso si el número es pequeño - Los enteros que pasan por
PHP_INT_MAX
se convierten automáticamente afloat
- Flota sobre los límites del sistema obtiene el valor
INF
- Las variables indefinidas son de tipo y valor
NULL
- Los enteros precedidos por
0
se convierten de octal a decimal (por convención) - La conversión de cadenas que contienen un entero con un
0
inicial a entero elimina el0
principal
Lista de algunas comparaciones exóticas:
Very strange: $a VS. $b $a>$b $a<$b $a<=$b $a>=$b $a==$b $a===$b float(NAN) float(-INF) false false false false false false float(NAN) float(0) false false false false false false float(NAN) float(1) false false false false false false float(NAN) float(INF) false false false false false false float(NAN) float(NAN) false false false false false false float(NAN) int(-1) false false false false false false float(NAN) int(0) false false false false false false float(NAN) int(1) false false false false false false
Igual pero no idéntico:
$a VS. $b $a>$b $a<$b $a<=$b $a>=$b $a==$b $a===$b
NULL(NULL) array() false false true true true false NULL(NULL) bool(false) false false true true true false NULL(NULL) float(0) false false true true true false NULL(NULL) int(0) false false true true true false NULL(NULL) str('''') false false true true true false array() bool(false) false false true true true false bool(false) float(0) false false true true true false bool(false) int(0) false false true true true false str('''') bool(false) false false true true true false bool(false) str(''0'') false false true true true false float(-INF) bool(true) false false true true true false bool(true) float(1) false false true true true false float(INF) bool(true) false false true true true false float(NAN) bool(true) false false true true true false bool(true) int(-1) false false true true true false bool(true) int(1) false false true true true false bool(true) str("/0") false false true true true false bool(true) str(''+'') false false true true true false bool(true) str(''-'') false false true true true false bool(true) str(''01'') false false true true true false bool(true) str(''1'') false false true true true false bool(true) str(''false'') false false true true true false str(''text'') bool(true) false false true true true false str(''true'') bool(true) false false true true true false int(0) float(0) false false true true true false str("/0") float(0) false false true true true false str('''') float(0) false false true true true false str(''+'') float(0) false false true true true false str(''-'') float(0) false false true true true false str(''0'') float(0) false false true true true false str(''false'') float(0) false false true true true false str(''text'') float(0) false false true true true false str(''true'') float(0) false false true true true false int(1) float(1) false false true true true false float(1) str(''01'') false false true true true false float(1) str(''1'') false false true true true false str("/0") int(0) false false true true true false str('''') int(0) false false true true true false str(''+'') int(0) false false true true true false str(''-'') int(0) false false true true true false int(0) str(''0'') false false true true true false str(''false'') int(0) false false true true true false str(''text'') int(0) false false true true true false str(''true'') int(0) false false true true true false int(1) str(''01'') false false true true true false int(1) str(''1'') false false true true true false str(''1'') str(''01'') false false true true true false
Más bajo y más grande al mismo tiempo?
$a VS. $b $a>$b $a<$b $a<=$b $a>=$b $a==$b $a===$b float(NAN) str("/0") true true true true false false float(NAN) str('''') true true true true false false float(NAN) str(''+'') true true true true false false float(NAN) str(''-'') true true true true false false float(NAN) str(''0'') true true true true false false float(NAN) str(''01'') true true true true false false float(NAN) str(''1'') true true true true false false float(NAN) str(''false'') true true true true false false float(NAN) str(''text'') true true true true false false float(NAN) str(''true'') true true true true false false
Igual Y idéntico:
$a VS. $b $a>$b $a<$b $a<=$b $a>=$b $a==$b $a===$b NULL(NULL) NULL(NULL) false false true true true true float(-INF) float(-INF) false false true true true true float(INF) float(INF) false false true true true true
Menor o Mayor:
$a VS. $b $a>$b $a<$b $a<=$b $a>=$b $a==$b $a===$b
NULL(NULL) bool(true) false true true false false false float(-INF) NULL(NULL) true false false true false false NULL(NULL) float(1) false true true false false false float(INF) NULL(NULL) true false false true false false float(NAN) NULL(NULL) true false false true false false NULL(NULL) int(-1) false true true false false false NULL(NULL) int(1) false true true false false false NULL(NULL) str("/0") false true true false false false NULL(NULL) str(''+'') false true true false false false NULL(NULL) str(''-'') false true true false false false NULL(NULL) str(''0'') false true true false false false NULL(NULL) str(''01'') false true true false false false NULL(NULL) str(''1'') false true true false false false NULL(NULL) str(''false'') false true true false false false NULL(NULL) str(''text'') false true true false false false NULL(NULL) str(''true'') false true true false false false array() bool(true) false true true false false false float(-INF) array() false true true false false false array() float(0) true false false true false false array() float(1) true false false true false false float(INF) array() false true true false false false float(NAN) array() false true true false false false array() int(-1) true false false true false false array() int(0) true false false true false false array() int(1) true false false true false false array() str("/0") true false false true false false str('''') array() false true true false false false array() str(''+'') true false false true false false array() str(''-'') true false false true false false array() str(''0'') true false false true false false array() str(''01'') true false false true false false array() str(''1'') true false false true false false array() str(''false'') true false false true false false array() str(''text'') true false false true false false array() str(''true'') true false false true false false bool(true) bool(false) true false false true false false float(-INF) bool(false) true false false true false false float(1) bool(false) true false false true false false float(INF) bool(false) true false false true false false float(NAN) bool(false) true false false true false false bool(false) int(-1) false true true false false false int(1) bool(false) true false false true false false bool(false) str("/0") false true true false false false bool(false) str(''+'') false true true false false false bool(false) str(''-'') false true true false false false bool(false) str(''01'') false true true false false false str(''1'') bool(false) true false false true false false bool(false) str(''false'') false true true false false false str(''text'') bool(false) true false false true false false str(''true'') bool(false) true false false true false false bool(true) float(0) true false false true false false bool(true) int(0) true false false true false false str('''') bool(true) false true true false false false bool(true) str(''0'') true false false true false false float(-INF) float(0) false true true false false false float(-INF) float(1) false true true false false false float(INF) float(-INF) true false false true false false float(-INF) int(-1) false true true false false false float(-INF) int(0) false true true false false false float(-INF) int(1) false true true false false false float(-INF) str("/0") false true true false false false float(-INF) str('''') false true true false false false float(-INF) str(''+'') false true true false false false float(-INF) str(''-'') false true true false false false float(-INF) str(''0'') false true true false false false float(-INF) str(''01'') false true true false false false float(-INF) str(''1'') false true true false false false float(-INF) str(''false'') false true true false false false float(-INF) str(''text'') false true true false false false float(-INF) str(''true'') false true true false false false float(1) float(0) true false false true false false float(INF) float(0) true false false true false false float(0) int(-1) true false false true false false int(1) float(0) true false false true false false float(0) str(''01'') false true true false false false str(''1'') float(0) true false false true false false float(INF) float(1) true false false true false false float(1) int(-1) true false false true false false float(1) int(0) true false false true false false float(1) str("/0") true false false true false false str('''') float(1) false true true false false false float(1) str(''+'') true false false true false false float(1) str(''-'') true false false true false false float(1) str(''0'') true false false true false false float(1) str(''false'') true false false true false false str(''text'') float(1) false true true false false false str(''true'') float(1) false true true false false false float(INF) int(-1) true false false true false false float(INF) int(0) true false false true false false float(INF) int(1) true false false true false false float(INF) str("/0") true false false true false false float(INF) str('''') true false false true false false float(INF) str(''+'') true false false true false false float(INF) str(''-'') true false false true false false float(INF) str(''0'') true false false true false false float(INF) str(''01'') true false false true false false float(INF) str(''1'') true false false true false false float(INF) str(''false'') true false false true false false float(INF) str(''text'') true false false true false false float(INF) str(''true'') true false false true false false int(0) int(-1) true false false true false false int(1) int(-1) true false false true false false str("/0") int(-1) true false false true false false str('''') int(-1) true false false true false false str(''+'') int(-1) true false false true false false str(''-'') int(-1) true false false true false false str(''0'') int(-1) true false false true false false int(-1) str(''01'') false true true false false false str(''1'') int(-1) true false false true false false str(''false'') int(-1) true false false true false false str(''text'') int(-1) true false false true false false str(''true'') int(-1) true false false true false false int(1) int(0) true false false true false false int(0) str(''01'') false true true false false false str(''1'') int(0) true false false true false false int(1) str("/0") true false false true false false str('''') int(1) false true true false false false int(1) str(''+'') true false false true false false int(1) str(''-'') true false false true false false int(1) str(''0'') true false false true false false int(1) str(''false'') true false false true false false str(''text'') int(1) false true true false false false str(''true'') int(1) false true true false false false str('''') str("/0") false true true false false false str(''+'') str("/0") true false false true false false str(''-'') str("/0") true false false true false false str("/0") str(''0'') false true true false false false str("/0") str(''01'') false true true false false false str(''1'') str("/0") true false false true false false str(''false'') str("/0") true false false true false false str(''text'') str("/0") true false false true false false str(''true'') str("/0") true false false true false false str('''') str(''+'') false true true false false false str('''') str(''-'') false true true false false false str('''') str(''0'') false true true false false false str('''') str(''01'') false true true false false false str('''') str(''1'') false true true false false false str('''') str(''false'') false true true false false false str('''') str(''text'') false true true false false false str('''') str(''true'') false true true false false false str(''-'') str(''+'') true false false true false false str(''+'') str(''0'') false true true false false false str(''+'') str(''01'') false true true false false false str(''1'') str(''+'') true false false true false false str(''false'') str(''+'') true false false true false false str(''text'') str(''+'') true false false true false false str(''true'') str(''+'') true false false true false false str(''-'') str(''0'') false true true false false false str(''-'') str(''01'') false true true false false false str(''1'') str(''-'') true false false true false false str(''false'') str(''-'') true false false true false false str(''text'') str(''-'') true false false true false false str(''true'') str(''-'') true false false true false false str(''0'') str(''01'') false true true false false false str(''1'') str(''0'') true false false true false false str(''false'') str(''0'') true false false true false false str(''text'') str(''0'') true false false true false false str(''true'') str(''0'') true false false true false false str(''false'') str(''01'') true false false true false false str(''text'') str(''01'') true false false true false false str(''true'') str(''01'') true false false true false false str(''1'') str(''false'') false true true false false false str(''text'') str(''1'') true false false true false false str(''true'') str(''1'') true false false true false false str(''text'') str(''false'') true false false true false false str(''true'') str(''false'') true false false true false false str(''true'') str(''text'') true false false true false false
$a > $b > $c
acertijo cuando: $a
no es mayor que $c
.
A<C : float(NAN) > str(''a'') > str('''') A<C : float(NAN) > str(''a'') > str(''1'') A<C : float(NAN) > str(''a'') > str(''A'') A<C : float(NAN) > str(''a'') > str(''0'') A<C : float(NAN) > str(''1'') > str('''') A<C : float(NAN) > str(''1'') > str(''0'') A<C : float(NAN) > str(''A'') > str('''') A<C : float(NAN) > str(''A'') > str(''1'') A<C : float(NAN) > str(''A'') > str(''0'') A<C : float(NAN) > str(''0'') > str('''') A<C : str('''') > float(NAN) > str(''a'') A<C : str('''') > float(NAN) > str(''1'') A<C : str('''') > float(NAN) > str(''A'') A<C : str('''') > float(NAN) > str(''0'') A<C : str(''a'') > str('''') > float(NAN) A<C : str(''a'') > str(''1'') > float(NAN) A<C : str(''a'') > str(''A'') > float(NAN) A<C : str(''a'') > str(''0'') > float(NAN) A<C : str(''0'') > str('''') > float(NAN) A==C : bool(true) > str('''') > float(NAN) A==C : bool(true) > str('''') > float(-INF) A==C : bool(true) > str('''') > int(-1) A==C : bool(true) > str('''') > float(-1) A==C : bool(true) > array() > float(NAN) A==C : bool(true) > array() > float(INF) A==C : bool(true) > array() > float(-INF) A==C : bool(true) > array() > str(''a'') A==C : bool(true) > array() > int(1) A==C : bool(true) > array() > float(1) A==C : bool(true) > array() > str(''1'') A==C : bool(true) > array() > str(''A'') A==C : bool(true) > array() > int(-1) A==C : bool(true) > array() > float(-1) A==C : bool(true) > int(0) > float(-INF) A==C : bool(true) > int(0) > int(-1) A==C : bool(true) > int(0) > float(-1) A==C : bool(true) > str(''0'') > float(NAN) A==C : bool(true) > str(''0'') > float(-INF) A==C : bool(true) > str(''0'') > int(-1) A==C : bool(true) > str(''0'') > float(-1) A==C : bool(true) > float(0) > float(-INF) A==C : bool(true) > float(0) > int(-1) A==C : bool(true) > float(0) > float(-1) A==C : int(1) > str(''a'') > str(''1'') A==C : int(1) > str(''A'') > str(''1'') A==C : float(1) > str(''a'') > str(''1'') A==C : float(1) > str(''A'') > str(''1'') A==C : str(''a'') > str(''1'') > int(0) A==C : str(''a'') > str(''1'') > float(0) A==C : str('''') > float(-INF) > NULL(NULL) A==C : str('''') > float(-INF) > bool(false) A==C : str('''') > int(-1) > NULL(NULL) A==C : str('''') > int(-1) > bool(false) A==C : str('''') > float(-1) > NULL(NULL) A==C : str('''') > float(-1) > bool(false) A==C : array() > float(NAN) > NULL(NULL) A==C : array() > float(NAN) > bool(false) A==C : array() > float(INF) > NULL(NULL) A==C : array() > float(INF) > bool(false) A==C : array() > float(-INF) > NULL(NULL) A==C : array() > float(-INF) > bool(false) A==C : array() > str(''a'') > NULL(NULL) A==C : array() > str(''a'') > bool(false) A==C : array() > int(1) > NULL(NULL) A==C : array() > int(1) > bool(false) A==C : array() > float(1) > NULL(NULL) A==C : array() > float(1) > bool(false) A==C : array() > str(''1'') > NULL(NULL) A==C : array() > str(''1'') > bool(false) A==C : array() > str(''A'') > NULL(NULL) A==C : array() > str(''A'') > bool(false) A==C : array() > str(''0'') > NULL(NULL) A==C : array() > int(-1) > NULL(NULL) A==C : array() > int(-1) > bool(false) A==C : array() > float(-1) > NULL(NULL) A==C : array() > float(-1) > bool(false) A==C : str('''') > float(NAN) > bool(false) A==C : str('''') > float(NAN) > NULL(NULL) A==C : str(''A'') > str(''1'') > int(0) A==C : str(''A'') > str(''1'') > float(0) A==C : int(0) > float(-INF) > NULL(NULL) A==C : int(0) > float(-INF) > bool(false) A==C : int(0) > int(-1) > NULL(NULL) A==C : int(0) > int(-1) > bool(false) A==C : int(0) > float(-1) > NULL(NULL) A==C : int(0) > float(-1) > bool(false) A==C : str(''0'') > float(NAN) > bool(false) A==C : str(''0'') > float(-INF) > bool(false) A==C : str(''0'') > int(-1) > bool(false) A==C : str(''0'') > float(-1) > bool(false) A==C : float(0) > float(-INF) > NULL(NULL) A==C : float(0) > float(-INF) > bool(false) A==C : float(0) > int(-1) > NULL(NULL) A==C : float(0) > int(-1) > bool(false) A==C : float(0) > float(-1) > NULL(NULL) A==C : float(0) > float(-1) > bool(false) A===C : str(''0'') > float(NAN) > str(''0'') A===C : str('''') > float(NAN) > str('''') A===C : str(''a'') > float(NAN) > str(''a'') A===C : str(''1'') > float(NAN) > str(''1'') A===C : str(''A'') > float(NAN) > str(''A'')
Comparación de cuerdas divertida: ''Queen'' >
''King'' >
''Jack'' >
''Ace''
También consulte las tablas de comparación de tipos de PHP que cubren pares:
-
isset()
eis_null()
-
if()
yempty()
- booleano
==
vs.===
Compruebe las diferencias entre las versiones de PHP en vivo en. http://3v4l.org/MAfDu .