PHP 8 ya está disponible! y viene con una serie de novedades muy esperadas, una de ellas es la mejora de su algoritmo de comparación inteligente para operadores no estrictos entre cadenas de texto y números, especialmente el operador de igualdad == ( no estricta).

Versiones antiguas

Antes de PHP 8 los algoritmos para realizar comparaciones no estrictas entre valores de tipo string y valores numéricos funcionaban al transformar el valor de la cadena en un valor de tipo numérico, y luego compararlo directamente con el operando integer o float.

En lenguajes de programación débilmente tipados como PHP, el operador de igualdad no estricta nos permite comparar los valores de variables que contienen tipos de datos diferentes.

Pero en algunos casos esto arrojaba resultados inesperados, especialmente si el valor del operando numérico es 0. Por ejemplo, si evaluáramos la comparación 0 == "foobar" en PHP 7.4 (o inferior), obtendríamos el siguiente resultado:

var_dump(0 == "foobar");
// bool(true);

La evaluación de igualdad devuelve true aunque la cadena no contenga ningún carácter numérico.

Esto sucede porque las versiones antiguas del algoritmo interpretan la ausencia de caracteres numéricos en un string como equivalente a 0, devolviendo este valor en la comparación.

Algunos ejemplos más del algoritmo:

Comparación    | Resultados 
------------------------------
 0 == "0"      | true
 0 == "0.0"    | true
 0 == ""       | true
 0 == "foo"    | true
31 == "31"     | true
31 == "   31"  | true
31 == "31foo"  | true

Cómo has notado, en este ejemplo la comparación no estricta devuelve true en todos los casos. Incluso si comparamos 0 con una cadena vacía "" o con una palabra, en este caso "foo". La comparación también arrojará true aunque nuestro operando string también contenga caracteres alfanuméricos.

En versiones anteriores de PHP,  si el inicio de la cadena operando contiene caracteres numéricos, el algoritmo de comparación convertirá dichos caracteres a un valor numérico ignorando el resto de la cadena. Por el contrario, si la cadena contiene números pero no inicia con símbolos numéricos, la comparación devolverá false siempre que el valor del operando numérico no sea 0.

En versiones previas de PHP, el uso descuidado del algoritmo de comparación no estricta es propenso a generar resultados inesperados o contra-intuitivos, lo que puede causar confusión entre programadores novatos o en programadores acostumbrados a trabajar con lenguajes fuertemente tipados, causando a su vez bugs en nuestro código.

Por esa razón, en PHP se considera una buena práctica evitar el operador == y se recomienda realizar comparaciones de igualdad estricta === cuando sea posible.

Comparaciones en PHP 8

El algoritmo de PHP 8 corrige estos fallos de la siguiente forma:

Al comparar un número contra una cadena cuyo valor sea numérico, PHP 8 se encargará de convertir el contenido de esta cadena en un número y luego realizará la comparación entre ambos valores numéricos, tal como funciona en versiones anteriores.

Si la cadena contiene algún carácter no numérico, PHP 8 transformará el número de la comparación en una cadena y realizará la comparación entre ambas cadenas, cambiando el comportamiento de la siguiente manera:

Comparación    | PHP 7        | PHP 8
--------------------------------------------
 0 == "0"      | true         | true
 0 == "0.0"    | true         | true
 0 == ""       | true         | false
 0 == "foo"    | true         | false
31 == "31"     | true         | true
31 == "   31"  | true         | true
31 == "31foo"  | true         | false

Ahora, vemos que en PHP 8 la comparación de igualdad == arrojará false si evaluamos cualquier número con una cadena que contenga letras o caracteres que no sean numéricos (exceptuando espacios y puntos decimales). Permitiendo realizar comparaciones entre tipos de datos distintos con mayor precisión y disminuyendo la probabilidad de crear bugs en el código, pero manteniendo la versatilidad característica de los lenguajes débilmente tipados.

Las nuevas comparaciones inteligentes de PHP 8 no son retro-compatibles. Pues implican un cambio importante en el funcionamiento y la semántica del código. Si planeas actualizar tus aplicaciones a PHP 8 pero éstas usan operadores de igualdad no estricta, deberás realizar pruebas para detectar y solucionar cualquier posible problema antes de actualizar.

Únete a nuestra comunidad en Discord y comparte con los usuarios y autores de Styde, 100% gratis.

Únete hoy

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.

Lección anterior Nuevo operador Nullsafe en PHP 8 Lección siguiente Nuevas funciones de cadena en PHP 8