Manipulación de tipos
PHP no requiere una definición de tipo explícita en las declaraciones de variables.
En este caso, el tipo de una variable se determina en función del valor que tiene almacenado.
Es decir, si una string se asigna a la variable
$var, entonces $var es de tipo
string. Si después se asigna un valor int a
$var, será de tipo int.
PHP puede intentar convertir el tipo de un valor en otro automáticamente
en ciertos contextos. Los diferentes contextos que existen son:
-
Numérico
-
String
-
Lógico
-
Integral y string
-
Comparativo
-
Función
Nota:
Cuando un valor necesita ser interpretado como un tipo diferente,
el valor en sí no cambia de tipo.
Para forzar una variable a ser evaluada como un tipo particular, ver la
sección sobre casting de tipo.
Para cambiar el tipo de una variable, ver la función settype().
Contextos numéricos
Este es el contexto al utilizar un
operador aritmético.
En este contexto, si uno de los operandos es un float (o
no interpretable como int), ambos operandos se interpretan
como floats, y el resultado será un float.
De lo contrario, los operandos se interpretan como ints,
y el resultado será también un int.
A partir de PHP 8.0.0, si uno de los operandos no puede ser interpretado como
TypeError se lanza.
Contextos integrales y string
Este es el contexto al utilizar un
operador bit a bit.
En este contexto, si todos los operandos son de tipo string
entonces el resultado será también una string.
De lo contrario, los operandos se interpretarán como ints,
y el resultado será también un int.
A partir de PHP 8.0.0, si uno de los operandos no puede ser interpretado,
se lanza una TypeError.
Contextos comparativos
Este es el contexto al utilizar un
operador de comparación.
Las conversiones de tipos que se producen en este contexto se explican
en el tabla
Comparación con varios tipos.
Contextos de funciones
Este es el contexto cuando un valor se pasa a un parámetro o propiedad
tipada o se devuelve desde una función que declara un tipo de retorno.
En este contexto, el valor debe ser una valor del tipo.
Existen dos excepciones, la primera es la siguiente: si el valor es de
tipo int y el tipo declarado es float, entonces
el entero se convierte en número de coma flotante.
La segunda es: si el tipo declarado es un tipo escalar
, el valor es convertible en un tipo escalar, y el modo de tipado coercitivo
está activo (por omisión), el valor puede ser convertido en un valor escalar aceptado.
Ver a continuación para una descripción de este comportamiento.
Advertencia
Las funciones internas
fuerzan automáticamente null
a los tipos escalares,
este comportamiento está OBSOLETO a partir de PHP 8.1.0.
Tipado coercitivo con declaraciones de tipo simples
-
Tipo de declaración bool: valor se interpreta como bool.
-
Tipo de declaración int: valor se interpreta como int
si la conversión está bien definida. Por ejemplo, la cadena es
numérica.
-
Tipo de declaración float: valor se interpreta como float
si la conversión está bien definida. Por ejemplo, la cadena es
numérica.
-
Tipo de declaración string: valor se interpreta como string.
Tipado coercitivo con uniones de tipo
Cuando strict_types
no está activado, las
declaraciones de tipo escalar están sujetas a restricciones de tipo
implícitas limitadas.
Si el tipo exacto del valor no forma parte de la unión, el tipo objetivo
se elige en el siguiente orden de preferencia:
-
int
-
float
-
string
-
bool
Si el tipo existe en la unión y el valor puede ser forzado a
este tipo utilizando la semántica de verificación de tipo existente de PHP, entonces el tipo es elegido.
Precaución
A título de excepción, si el valor es una cadena y int y float forman
ambos parte de la unión, el tipo preferido se determina por la
semántica de cadena numérica.
Por ejemplo, para "42"
int es elegido,
mientras que para "42.0"
float es elegido.
Nota:
Los tipos que no forman parte de la lista de preferencias anterior no
son objetivos admisibles para la coerción implícita. En particular,
ninguna restricción implícita a los tipos null
y
false
se produce.
Ejemplo #1 Ejemplo de tipos restringidos a una parte del tipo de la unión
<?php
// int|string
42 --> 42 // tipo exacto
"42" --> "42" // tipo exacto
new ObjectWithToString --> "Result of __toString()"
// objeto nunca compatible con int, recurrir a string
42.0 --> 42 // float compatible con int
42.1 --> 42 // float compatible con int
1e100 --> "1.0E+100" // float demasiado grande para el tipo int, recurrir a string
INF --> "INF" // float demasiado grande para el tipo int, recurrir a string
true --> 1 // bool compatible con int
[] --> TypeError // array no compatible con int o string
// int|float|bool
"45" --> 45 // int string numérico
"45.0" --> 45.0 // float string numérico
"45X" --> true // no string numérico, recurrir a bool
"" --> false // no string numérico, recurrir a bool
"X" --> true // no string numérico, recurrir a bool
[] --> TypeError // array no compatible con int, float o bool
?>
Cast de tipo
El casting de tipo convierte el valor a un tipo dado escribiendo el tipo
entre paréntesis antes del valor a convertir.
Ejemplo #2 Conversión de tipo
<?php
$foo = 10; // $foo es un integer
$bar = (bool) $foo; // $bar es un bool
var_dump($bar);
?>
Los casts permitidos son:
Nota:
(integer)
es un alias del cast (int)
.
(boolean)
es un alias del cast (bool)
.
(binary)
es un alias del cast (string)
.
(double)
y (real)
son alias del
cast (float)
.
Estos casts no utilizan el nombre de tipo canónico y no son recomendados.
Advertencia
El alias de cast (real)
está obsoleto a partir de PHP 8.0.0.
Advertencia
El cast (unset)
fue declarado obsoleto a partir de PHP 7.2.0.
A notar que el cast (unset)
es idéntico a asignar el
valor NULL a una variable o una llamada.
El cast (unset)
es eliminado a partir de PHP 8.0.0.
Precaución
El cast (binary)
y el prefijo b
existen únicamente para la compatibilidad ascendente. Actualmente
(binary)
y (string)
son idénticos,
pero esto puede cambiar: no se debe contar con ello.
Nota:
Los espacios en blanco se ignoran dentro de los paréntesis de un cast.
Así, los dos casts siguientes son equivalentes:
En lugar de transtypar una variable en una string, también es posible
rodear la variable con comillas dobles.
Ejemplo #3 Diferentes mecanismos de conversión
<?php
$foo = 10; // $foo es un integer
$str = "$foo"; // $str es una cadena
$fst = (string) $foo; // $fst es también una cadena
// Esto muestra "Son iguales"
if ($fst === $str) {
echo "Son iguales", PHP_EOL;
}
?>
Lo que ocurrirá exactamente al transtypar entre ciertos tipos
no es necesariamente evidente. Para más información, ver estas secciones:
Nota:
Como PHP soporta la indexación en las strings
mediante posiciones utilizando la misma sintaxis que la indexación de array,
el siguiente ejemplo es válido para todas las versiones de PHP:
Ejemplo #4 Uso de un índice de array con una cadena
<?php
$a = 'car'; // $a es una cadena de caracteres
$a[0] = 'b'; // $a sigue siendo una cadena de caracteres
echo $a; // bar
?>
Ver la sección sobre el acceso
a las cadenas por caracter para más información.