Desarrollo

Transformación de tipos de datos en PHP

Desarrollo PHP

En este sencillo artículo vamos a ver la transformación de tipos de datos, es decir, el que un tipo string se convierta en un tipo int, por ejemplo. Sin embargo, veremos que este sencillo tema puede dar más de sí de lo que parece.

Este será el último de una pequeña serie de artículos donde hemos visto algunas herramientas en PHP que nos pueden ayudar a mejorar nuestros programas con las constantes y amplían nuestro rango de acción con nuevas estructuras de control. No olvides acceder al índice de contenidos para ver todo lo publicado y lo que está por venir.

Manipulación de tipos

Al contrario que en muchos otros lenguajes de programación, en PHP no es necesario definir explícitamente el tipo de datos de nuestras variables por lo que la transformación de tipos de datos no siempre es necesaria para el programador, pues PHP lo hace automáticamente. Como hemos estado viendo y utilizando hasta ahora, podemos hacer esto sin ningún tipo de problema:

<?php
$variable1 = 'Hola'; // Esta variable es un string
$variable2 = 5; // Esta variable es un int
$variable3 = 7.8; // Esta variable es un float

$variable1 = 67; // Ahora $variable1 es un int, no un string
$variable2 = $variable3; // Ahora $variable2 es un float, no un int
$variable3 = 'Adiós'; // Ahora $variable3 es un string
?>

Como se ve claramente en este ejemplo, en ningún momento hemos indicado de qué tipo es cada variable. Automáticamente PHP convierte esa variable al tipo de datos adecuado sin que tengamos que indicarle nada ni realizar una transformación de tipos de datos.

Conversión automática de string a número

Un string, cuando es evaluado en un contexto numérico, se transforma automáticamente en un int o un float dependiendo del tipo de número. Es decir, que podemos sumarle un número a un string que contenga una representación de un número, que funciona sin problemas. Cuidado, una representación de un número al principio del string, pues si no es así, funciona pero no como esperábamos.

Obviamente sumar un 5 a un string que contenga ‘cuatro’ no va a funcionar como queremos (el resultado sería un 5), pero sumar ese 5 a un string que contenga ‘4 casas’ sí funcionará aunque nos parezca extraño, y ya veremos qué se obtiene. Veamos algunos ejemplos de transformación de tipos de datos:

<?php
$valor = 1 + "5"; // $valor es un int que contiene un 6
$valor = 1 + "5.5"; // $valor es un float que contiene un 6.5
$valor = 1 + "1.2e5"; // $valor es un int que contiene un 120001
$valor = 1 + "cinco"; // $valor es un int que contiene un 1
$valor = 1 + "cinco es 5"; // $valor es un int que contiene un 1
$valor = 1 + "4 casas"; // $valor es un int que contiene un 5
$valor = 1 + "3.2 pasteles"; // $valor es un float que contiene un 4.2
?>

Suponemos que los dos primeros ejemplos están claros. El tercer ejemplo utiliza una notación matemática que vimos en el momento de definir los tipos elementales en PHP. En cuanto al cuarto ejemplo, como vemos, sumar un número a un string que no tiene nada que ver con un número devuelve el número sin nada más. Lo mismo ocurre si en el string hay un número al final, como en el quinto ejemplo. Ya los dos últimos ejemplos son los que pueden parecer más raros, pues si al principio del string hay un número válido, entonces la operación se realiza sin problemas, como vemos en los ejemplos.

Más ejemplos de conversiones automáticas

Dejando un poco de lado los strings, podemos imaginar que los siguientes resultados son lógicos:

<?php
$valor = '1'; // $valor es un string
$valor += 1; // $valor es un int que contiene un 2
$valor = $valor + 1.5; // $valor es un float que contiene un 3.5
?>

Forzado de tipos

Podemos forzar que los valores que van a guardarse en una variable sean de un tipo definido por nosotros mismos realizando así la transformación de tipos de datos por nuestra cuenta. Así, podemos forzar a que un int sea un string, un string sea un booleano, un float sea un int, etc. Todo esto se realiza colocando, antes del valor a forzar, el nombre del tipo de datos entre paréntesis. Vamos a ver algunos forzados y los comentamos.

Forzar a int

<?php
$valor = (int) 10.5; // $valor contiene un 10
$valor = (int) 'Diez coma cinco'; // $valor contiene un 0
$valor = (int) '10.5'; // $valor contiene un 10
$valor = (int) true; // $valor contiene un 1
$valor = (int) array('Uno', 'Dos'); // $valor contiene un 1
?>

El primer ejemplo parece evidente. Si transformamos un float a int, nos estamos cargando su parte decimal. En el segundo ejemplo, al intentar convertir un string con texto a int, nos encontramos con que no se puede y, por ello, el valor que contendría la variable sería un 0. Sin embargo, si encuentra en el string al principio un número, lo convierte, de nuevo sin la parte decimal que hemos indicado. Convertir un booleano da 1 si es true y 0 si es false, mientras que cualquier conversión de un array nos va a dar un 1.

Forzar a float

<?php
$valor = (float) 10; // $valor contiene un 10.0
$valor = (float) 'Diez coma cinco'; // $valor contiene un 0
$valor = (float) '10.5'; // $valor contiene un 10.5
$valor = (float) true; // $valor contiene un 1.0
$valor = (float) array('Uno', 'Dos'); $valor contiene un 1.0
?>

Pocas diferencias en cuanto a forzar a float. Ahora, obviamente, si tenemos un int lo forzamos a float y simplemente tendrá parte decimal (vacía). Al igual que pasaba en el caso anterior, forzar un string a float también nos da un 0, mientras que si es un string con un número al principio, lo transforma correctamente, ahora además con su parte decimal. Tanto para los booleanos como los arrays, el comportamiento es igual que con el int, solo que ahora es un float.

Forzar a string

<?php
$valor = (string) 10; // $valor contiene un '10'
$valor = (string) 10.5; // $valor contiene un '10.5'
$valor = (string) true; // $valor contiene un '1'
$valor = (string) array('Uno', 'Dos'); // Aviso de error de conversión, $valor contiene 'Array'
?>

En este caso, y comenzando por el final, vemos que no puede realizar correctamente la conversión de un array en un string, siendo esta una transformación de tipos de datos no disponible realmente. Si están activos los mensajes de error, da un aviso de que hay un intento de convertir un array en un string. Esto no detiene el programa con un error fatal, pero, como vemos, en la variable contendremos la simple cadena “Array” que no es lo que buscábamos. En los otros ejemplos, no hay problema, pues ha convertido perfectamente los números en strings y el valor booleano también, con la representación de un ‘1’ para true. No, no esperemos que guarde la propia palabra ‘true’, pues no se comporta así.

Forzar a bool

<?php
$valor = (bool) 0; // $valor contiene false
$valor = (bool) 10.5; // $valor contiene true
$valor = (bool) 'Diez coma cinco'; // $valor contiene true
$valor = (bool) '10.5'; // $valor contiene true
$valor = (bool) ''; // $valor contiene false
$valor = (bool) array('Uno', 'Dos'); // $valor contiene true
$valor = (bool) array(); // $valor contiene false
?>

Cualquier valor que no esté vacío (como la cadena vacía o un array vacío) o sea 0, se transforma en un tipo booleano con el valor true. Mientras que en los casos donde coloquemos un cero o algo vacío nos encontraremos con un valor false. No hay más secretos y, en ocasiones, podremos utilizarlo en las condiciones de nuestros IF para comprobar si una variable está vacía o contiene un 0.

Forzar a array

<?php
$valor = (array) 10; // $valor contiene array(10)
$valor = (array) 10.5; // $valor contiene array(10.5)
$valor = (array) 'Diez coma cinco'; // $valor contiene array('Diez coma cinco')
$valor = (array) '10.5'; // $valor contiene array('10.5')
$valor = (array) true; // $valor contiene array(true)
?>

La última transformación de tipos de datos que vamos a ver es hacia un array. Como vemos, en todos los casos va a transformar el dato en un array con un elemento, el cual tendrá índice numérico 0. El elemento tendrá el tipo del elemento inicial, es decir, si transformamos un int, tendremos un array con ese elemento int en su interior. En definitiva, hacer este forzado nos devuelve un array con el mismo elemento que hemos querido forzar en su interior. Es como si “encapsuláramos” el elemento dentro del array.

Las funciones settype y gettype

Como para casi siempre en PHP, tenemos también unas funciones con las que podemos hacer casi todo lo que se realiza también por otros métodos, y este caso no es una excepción.

Todo lo que hemos visto anteriormente se puede realizar con la función settype. Esta función espera dos parámetros, el primero de los cuales es la variable a transformar y, el segundo, será a qué tipo de datos lo queremos transformar, indicándolo en forma de string. Es decir, que estas dos formas de transformación de tipos de datos son equivalentes:

<?php
$valor = 5;
// Forma con forzado de tipos
$valor = (string) $valor;
// Forma con la función settype
settype($valor, 'string');

// En ambos casos la variable $valor sería un string que contendría '5'
?>

Por su parte, la función gettype nos va a devolver el tipo de datos actual de la variable. Así, si en este ejemplo hubiéramos puesto un gettype($valor) justo después de definirlo, nos hubiera dado como resultado ‘int‘, mientras que si se lo hubiéramos puesto justo al final, nos hubiera dado como resultado ‘string’.

Tablas de comparación

Por último, os comparto este enlace al manual de PHP con unas muy útiles tablas para saber claramente qué va a devolver cada una de las comparaciones que se hacen, tanto con algunas de las herramientas vistas aquí, como otras que vimos en su momento como empty o is_null en el artículo de validaciones.

Para lo que hemos visto en este artículo, vemos todos los tipos de datos que devolvería la función gettype de un buen número de ejemplos posible. Así pues, puede ser una buena tabla para consultar cuando no sepamos muy bien por qué obtenemos el valor que obtenemos.

Resumen

La transformación de tipos de datos es una tarea sobre la cual, normalmente, no vamos a necesitar sus servicios, pues PHP se encarga en su mayor parte de hacer esta transformación de tipos de datos por sí mismo. Sin embargo, en algunas ocasiones (con arrays especialmente), conviene saber qué podemos y qué no podemos realizar por nuestra cuenta.

Conocidas estas nuevas herramientas, en el próximo artículo veremos el operador ternario, el cual nos puede ayudar a mejorar aún más el código.

Deja una respuesta