Ver Mensaje Individual
  #2 (permalink)  
Antiguo 23/02/2008, 18:41
AlvaroG
Invitado
 
Mensajes: n/a
Puntos:
Re: Fácil: Campo form devuelve un string y no un numero (mas largo)

Esto lo tenía como artículo en mi blog, antes de que sufriera un error en la base de datos...

Espero te sirva

------------------------------------------------------


¿Cómo hacer para estar seguro de que un parámetro obtenido por GET (o POST) es un número entero?
Intentando resolver esta pregunta he intentado varias técnicas a lo largo del tiempo, y haciendo esas pruebas he llegado a entender más sobre cómo funcionan las comparaciones y las conversiones automáticas de tipos en PHP.

Parto de la base de que no sirve usar una conversión directa con (int), o intval(), ya que si bien estaría seguro de que el valor que obtengo es un entero, eso no quiere decir que sea un valor válido, ya que cualquier cadena puede convertirse a entero (si no comienza con números, su valor es cero). Ante la duda, nada mejor que consultar la página sobre manipulación de tipos del manual de PHP.


Primer intento: is_int
La primera idea es comprobar con la función is_int.
Sin embargo, esto no funciona, porque PHP considera cadenas a estas variables.
¿Cómo lo sé? Por 2 motivos:

1.- La propia página del manual lo advierte: "Para probar si una variable es un número o una cadena numérica (como en el caso de la entrada de un formulario, que es siempre una cadena), debe usar is_numeric()".

2.- gettype($_GET['uno']);
Devuelve "string", aunque el valor de $_GET['uno'] sea 12, por ejemplo.

is_int($_GET['uno']);
Devuelve false, en el mismo caso que el anterior.


Segundo intento: is_numeric
is_numeric serviría, excepto porque también acepta números con coma (punto, en realidad). De nuevo, podríamos simplemente convertirlo a entero con (int), pero no sería el valor original y por lo tanto no sería un valor válido.

Tercer intento: comparación con entero
Otra opción puede ser hacer una comparación como
$_GET['var'] == (int) $_GET['var'];

En teoría funcionaría, pero no es así.
PHP es un tanto "especial" en lo que refiere a las conversiones de tipos: siempre que haya un entero en un lado de la comparación, convertirá el otro lado en entero.
Por lo tanto, la comparación SIEMPRE será cierta, ya que el lado izquierdo de la comparación será convertido también, resultando en lo mismo que si escribiese

(int) $_GET['var'] == (int) $_GET['var'];


Cuarto intento: comparación de idénticos
Bueno, si PHP convierte a entero ambos lados y por eso no sirve el ejemplo anterior, bastaría con usar el comparador ===, ¿no?
¡NO! Porque siempre serán de tipos diferentes, ya que como se dijo antes, las variables GET son tomadas como cadenas.

Quinto intento: complicado pero funciona
Finalmente decidí ir por algo más complejo pero que evita todos los problemas de los casos anteriores.
¿Qué hacer? La comparación con un entero es necesaria, porque después de todo lo que necesitamos es un entero, pero no podemos comparar una cadena con un entero porque la cadena será convertida...
Solución: volver a convertir al entero en cadena.

Código PHP:
if ( $_GET['var'] == (string) intval($_GET['var']) ) {
    echo 
"¡Es entero!";

Esa es la mejor solución que he encontrado, ¿alguien conoce alguna mejor?


-------------------------------------------

Distribuir como se quiera, siempre que se me mencione como autor


Saludos.