Tengo el siguiente código:
$item['price'] = 0;
/* Code to get item information goes in here */
if($item['price'] == 'e') {
$item['price'] = -1;
}
Su objetivo es inicializar el precio del artículo a 0 y luego obtener información sobre él. Si el precio se informa como 'e', significa un intercambio en lugar de una venta, que se almacena en una base de datos como un número negativo.
También existe la posibilidad de dejar el precio en 0, ya sea porque el artículo es un bono o porque el precio se fijará en un momento posterior.
Pero, siempre que no se establece el precio, lo que lo deja con el valor inicial de 0, el if
ciclo indicado arriba se evalúa como verdadero y el precio se establece en -1. Es decir, considera que 0 es igual a 'e'.
¿Cómo se puede explicar esto?
Cuando el precio se proporciona como 0 (después de la inicialización), el comportamiento es errático: a veces, si se evalúa como verdadero, a veces se evalúa como falso. *
if((string)$item['price'] == 'e')
corrige el comportamiento extraño. Consulte stackoverflow.com/a/48912540/1579327 para obtener más detallesRespuestas:
Está haciendo lo
==
que clasifica los tipos por usted.0
es un int, por lo que en este caso se convertirá'e'
en un int. Que no se puede analizar como uno y se convertirá en0
. ¡Una cuerda'0e'
se convertiría0
y coincidiría!Utilizar
===
fuente
Esto se debe a cómo PHP realiza la operación de
==
comparación que denota el operador de comparación :Como el primer operando es un número (
0
) y el segundo es una cadena ('e'
), la cadena también se convierte en un número (consulte también la tabla Comparación con varios tipos ). La página del manual sobre el tipo de datos de cadena define cómo se realiza la conversión de cadena a número :En este caso, la cadena es
'e'
y, por lo tanto, se evaluará como un flotante:Como
'e'
no comienza con datos numéricos válidos, se evalúa como flotante0
.fuente
evalúa
true
porque primero"ABC"
se convierte a entero y0
luego se compara con0
.Este es un comportamiento extraño del lenguaje PHP: normalmente uno esperaría
0
ser promovido a cadena"0"
y luego compararlo"ABC"
con un resultadofalse
. Quizás eso es lo que sucede en otros lenguajes como JavaScript, donde se"ABC" == 0
evalúa la comparación débilfalse
.Hacer una comparación estricta resuelve el problema:
evalúa
false
.Pero, ¿qué pasa si necesito comparar números como cadenas con números?
evalúa
false
porque los términos izquierdo y derecho son de diferente tipo.Lo que realmente se necesita es una comparación débil sin las trampas del malabarismo de tipo PHP.
La solución es promover explícitamente los términos a la cadena y luego hacer una comparación (estricto o débil ya no importa).
es
true
mientras
es
false
Aplicado al código original:
fuente
El operador == intentará hacer coincidir los valores incluso si son de diferentes tipos. Por ejemplo:
Si también necesita una comparación de tipos, use el operador ===:
fuente
Su problema es el operador doble igual, que encasillará al miembro derecho al tipo del izquierdo. Use estricto si lo prefiere.
Volvamos a su código (copiado arriba). En este caso, en la mayoría de los casos, $ item ['price'] es un número entero (excepto cuando es igual ae, obviamente). Como tal, según las leyes de PHP, PHP se convertirá
"e"
en entero, lo que cedeint(0)
. (¿No me crees?<?php $i="e"; echo (int)$i; ?>
).Para alejarse fácilmente de esto, use el operador triple igual (comparación exacta), que verificará el tipo y no se encasillará implícitamente.
PD: un dato divertido de PHP:
a == b
no implica esob == a
. Tome su ejemplo e inviértalo:if ("e" == $item['price'])
nunca se cumplirá realmente siempre que $ item ['price'] sea siempre un número entero.fuente
Existe un método bastante útil en PHP para validar una combinación de "0", "falso", "apagado" como == falso y "1", "encendido", "verdadero" como == verdadero, que a menudo se pasa por alto. Es particularmente útil para analizar argumentos GET / POST:
No es totalmente relevante para este caso de uso, pero dada la similitud y el hecho de que este es el resultado que la búsqueda tiende a encontrar cuando se hace la pregunta de validar (cadena) "0" como falso, pensé que ayudaría a otros.
http://www.php.net/manual/en/filter.filters.validate.php
fuente
Debería usar en
===
lugar de==
, porque el operador ordinario no compara los tipos. En su lugar, intentará encasillar los elementos.Mientras tanto, se
===
toma en consideración el tipo de artículos.===
significa "igual",==
significa "eeeeh ... un poco parece"fuente
if((string)$item['price']=='e'){ $item['price'] = -1; }
===
operadorCreo que es mejor mostrar con ejemplos que hice, mientras me encuentro con el mismo comportamiento extraño. Vea mi caso de prueba y espero que le ayude a comprender mejor el comportamiento:
fuente
Básicamente, utilice siempre el
===
operador, para garantizar la seguridad del tipo.fuente