En defensa de PHP

Monday 19 de May de 2008

Hace tiempo, Aurelianito puso en su blog un post acerca de un problema de PHP en particular, que
discutimos extensamente en sus comentarios.

El caso particular era:

< ? echo count == 0; ?> // imprime 1, mientras
< ? echo count == 0."\n"; ?> // no imprime nada.

Hay muchas cosas mal en este ejemplo (medio sacado por los pelos), y no son todas culpa del lenguaje:

  • count es una constante indefinida. Su valor es el string “count”;
  • El primer ejemplo es una comparación string-entero.
  • El segundo ejemplo es una comparación string-string.

El primer punto es una elección del lenguaje: prefiere devolver un string y tirar un warning, que morir. O sea, lo anterior es igual a:

< ? echo "count" == 0; ?> // imprime 1, mientras
< ? echo "count" == 0."\n"; ?> // no imprime nada.

El tercero es lo más lógico: . tiene mayor precedencia que ==, y dado que PHP es de tipos débiles y dinámicos, estoy comparando "const" con "0\n", que obviamente son diferentes. Aunque no imprime nada.

PHP tiene muchos valores para falso: 0, false, null, entre otros. Una expresión falsa devuelve null. < ? echo null; ?> no imprime nada. QED.

Hasta ahora, estamos bien.

Ahora viene la parte rara: "count" == 0 devuelve 1.

Esta es una comparación entre un string y un entero… que, empezando por ahí, no tiene sentido…
pero aún así me devuelve un valor (y uno inesperado, por decir poco).

Pero la comparación, como dije, no tiene sentido, entonces PHP intenta convertir ambos valores a un
tipo que pueda comparar. Lo que PHP decidió es, en vez de transformar el número a un string,
transforma el string a un número. Obviamente que las letras no son números1, así que el parser analiza el string hasta el primer caracter que no forme un número2 y devuelve el número que haya encontrado hasta ahora.

Por ejemplo:

< ?
assert("42" == 42);
assert("42a" == 42);
assert("4a2" == 4);
assert("a42" == 0);
//Y lo que nos importa:
assert("a" == 0);
?>

Y ahí tenemos por qué nuestro "count" == 0 devuelve 1.

Estoy completamente de acuerdo en que la respuesta tiene poco sentido, pero no es culpa del lenguaje
que el programador compare dos tipos de datos que no tienen que ver uno con el otro.

Ah, y para los que prefieren que “42″ no sea igual a 42, pueden usar ===, una comparación mucho más estricta, que también revisa el tipo de ambos valores.

  1. No probé si parsea
    hex, pero… vamos…
  2. Nuevamente,
    no revisé si remueve los espacios

4 Comentarios a “En defensa de PHP”

  1. Juan dijo:

    Tuesday 20 de May de 2008, 5:53 am

    Y dale con los short open tags :P

  2. Alberto dijo:

    Tuesday 20 de May de 2008, 7:33 am

    Aguanten los short open tag, quien vio un <%asp ;)

  3. Tordek dijo:

    Tuesday 20 de May de 2008, 1:01 pm

    Los Short Open Tags no son tan malos como las magic quotes, dejalos en paz…

  4. Juan dijo:

    Monday 26 de May de 2008, 3:00 am

    Note: Using short tags should be avoided when developing applications or libraries that are meant for redistribution, or deployment on PHP servers which are not under your control, because short tags may not be supported on the target server. For portable, redistributable code, be sure not to use short tags.

    Basic syntax

    No pude encontrar el link en el manual que dice que el uso de las S.O.T. está deprecado, pero recuerdo haberlo comentado en tu blog.

Comentá:

XHTML permitido: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="">