2009-03-23 8 views
26

Estoy realmente confundido sobre por qué funciona esta operación. ¿Alguien puede explicarlo?Comparando String a Entero da resultados extraños

$test1 = "d85d1d81b25614a3504a3d5601a9cb2e"; 
$test2 = "3581169b064f71be1630b321d3ca318f"; 

if ($test1 == 0) 
    echo "Test 1 is Equal!?"; 
if ($test2 == 0) 
    echo "Test 2 is Equal!?"; 

// Returns: Test 1 is Equal!? 

Para mayor claridad, estoy tratando de comparar la cadena "0" a los $test variables. Ya sé arreglar el código que puedo adjuntar (como debería) 0 en "" s

Me pregunto si esto es un error de PHP, un error del servidor, o de alguna manera una operación válida. De acuerdo con http://us3.php.net/types.comparisons este no debería haber funcionado.

Editar: Raye eso, aparentemente menciona que las comparaciones sueltas entre la cadena y 0 son verdaderas. Pero todavía no sé por qué.

Editar 2: He revisado mi pregunta, ¿por qué el valor $test2 de "3581169b064f71be1630b321d3ca318f" no funciona?

+0

¿cuál valor de $ test no funciona? –

+0

Si ejecuta el código, solo emite 'Test 1 is Equal!?' –

+0

echo (int) $ test2; – OIS

Respuesta

28

From the PHP manual: conversión

de cadenas a números

Cuando se evalúa una cadena en un contexto numérico , el valor y tipo resultantes se determinó como sigue.

La cadena se evaluará como un flotador si contiene cualquiera de los caracteres '', 'e', ​​o 'E'. De lo contrario, se evaluará como un entero .

El valor viene dado por la porción inicial de la cadena. Si la cadena comienza con datos numéricos válidos, este será el valor utilizado. De lo contrario, el valor será 0 (cero). Los datos numéricos válidos son un signo opcional, seguido de uno o más dígitos (opcionalmente que contiene un punto decimal), seguido de por un exponente opcional. El exponente es una 'e' o 'E' seguida de uno o dígitos más.

+0

Todavía no creo que deba convertirse a un 0, o al menos si comienza con un número que no se convertirá a un decimal si hay caracteres erróneos en la cadena. –

+2

PHP no tiene el tipo "NaN" como Javascript (otro lenguaje de tipo suelto) por lo que tiene que convertirse a 0 ya que no habría otra manera (la conversión a NULL no funcionaría porque cos NULL también se convierte a 0). Creo que la respuesta es no usar una comparación suelta (==), o validar primero la cadena. – thomasrutter

+1

** Además de esta respuesta **, al comparar 2 elementos con el operador '==', se convierte a tipo común. se menciona aquí. http://www.php.net/manual/en/language.operators.comparison.php – Nis

9

Conversión de tipo utilizando el operador ==

El operador == es una comparación mecanografiado débilmente. Convertirá ambos en un tipo común y los comparará. La forma en que las cadenas se convierten en números enteros es explained here.

Tenga en cuenta que el page you linked to no lo contradice. Consulte la segunda tabla, donde dice que la comparación del número entero 0 con una cadena "php" utilizando == será verdadera.

Lo que ocurre es que la cadena se convierte en entero, y las cadenas no numéricas (cadenas que no contienen o comienzan con un número) se convierten en 0.

numérico vs cadenas no numéricos

Una cadena que consta de un número, o comienza con un número, se considera una cadena numérica . Si la cadena tiene otros caracteres después de ese número, estos se ignoran.

Si una cadena comienza con un carácter que no se puede interpretar como parte de una serie, entonces es una cadenano numérico y se convertirá en 0. Esto no significa que una cadena numérica tenga que comenzar con un dígito (0-9); por ejemplo, "-1" es una cadena numérica porque el signo menos es parte de un número en ese caso.

Así, por ejemplo, su cadena "d85d1d81b25614a3504a3d5601a9cb2e" no comienza con un número, por lo que se convertiría en 0. Pero su segunda cadena "3581169b064f71be1630b321d3ca318f" se convertiría en el número entero 3581169. Es por eso que su segunda prueba no funciona de la misma manera.

Lo que debe hacer

Es probable que desee:

if ($test1 === "0") 

Aviso el uso de triples iguales en lugar de una doble iguales.Esto asegura que lo que está comparando es una cadena que contiene el dígito cero solamente, y evita cualquier tipo de conversión.

6

Después de algunas investigaciones, resulta que aidan del manual de PHP mencionado que cualquier cadena que no comience con un número se convertirá en 0 cuando se convierte como un entero.

Esto significa que:

("php" == 0) === true 
("1php" == 0) === false 

muy molesto y no están bien documentados. Estaba en la parte inferior de los comentarios en la página de comparación de tipos.

+1

Sí, pensé que era eso. Mala documentación de hecho. –

+0

No creo que sea una documentación deficiente. La conversión de tipo implícita es un elemento fundamental de PHP, que se explica muy bien en el manual en la sección Tipos, en particular en la sección Tipo Malabares. == es una comparación vagamente tipada; usar === en su lugar puede ayudar a prevenir situaciones confusas. – thomasrutter

+0

Consulte también "Conversión de cadenas en números" en http://us3.php.net/manual/en/language.types.string.php#language.types.string.conversión – thomasrutter

1

He estado usando algunas conversiones y comparaciones para probar si un cadena numérica es un número:

$test1="19de6a91d2ca9d91721d82f1bd8102b6"; 
    echo (float)$test1==$test1; //TRUE 
    echo is_float($test1); //FALSE 

    //Converting the string to float and then converting it to string and compare will do the trick 
    echo (string)((float)$test1)==(string)$test1; //FALSE 


$test2="5.66"; 
    echo (float)$test2==$test2; //TRUE 

    //Testing the numeric string using `is_float` wont give the expected result 
    echo is_float($test2); //FALSE 

    echo (string)((float)$test2)==(string)$test2; //TRUE 
2
$test1 = "d85d1d81b25614a3504a3d5601a9cb2e"; 

esta cadena comienza con una "d", que no es válida número, la var se resolverá en 0 y su prueba n. ° 1 pasará.

$test2 = "3581169b064f71be1630b321d3ca318f"; 

esta cadena comienza con 3,581,169, que es un número válido, por lo que la var resolverá a ese valor que no es igual a 0. Así su prueba # 2 no pasará.

Cuestiones relacionadas