PHP Tipos de Dados

Na aula de Variáveis você guardou textos e números em caixas. Cada valor guardado é de um tipo: o nome "Ana" é um texto, a idade 29 é um número inteiro, a altura 1.65 é um número com casas decimais. O tipo decide o que dá para fazer com o valor: números se somam, textos se juntam, listas se percorrem. Nesta aula você conhece todos os tipos do PHP e aprende a perguntar ao PHP "de que tipo é isto?".

Você vai aprender
  • Os tipos do PHP: string, int, float, bool, array, object, null, callable e resource.
  • O que é tipagem dinâmica e por que 10 e "10" não são a mesma coisa.
  • Como descobrir o tipo de um valor com var_dump, gettype e get_debug_type.
  • Como testar um tipo com as funções is_string, is_int, is_float…

Os programas desta aula rodaram com o PHP 8.5 na máquina fictícia da Ana, na pasta ~/site. Cada tipo tem uma aula própria mais adiante; aqui é o "mapa" de todos eles.


A ideia: cada coisa no seu recipiente

Na cozinha da Ana, o leite fica na garrafa, os ovos na caixinha, a farinha no pote. Ninguém tenta "somar" um ovo com um pote de farinha: cada coisa tem o seu jeito de ser usada. Com os valores de um programa é igual:

  • Com números você faz contas: 4.5 * 2 dá 9.
  • Com textos você junta, corta, procura palavras: "Ana" . " Souza".
  • Com verdadeiro ou falso você toma decisões: "se o cliente está logado, mostre o carrinho".
  • Com listas você guarda vários valores juntos: a lista de compras inteira numa variável só.

O tipo de dado (ou só tipo) é essa "categoria" do valor. O PHP olha o tipo para saber o que fazer quando você escreve +, ., if ou foreach.


Os tipos do PHP

TipoNome em portuguêsGuardaExemplosAula
stringtexto ("cadeia de caracteres")Letras, palavras, frases"Ana", 'maçã', ""Strings
intinteiroNúmeros sem parte decimal29, -5, 0int e float
floatponto flutuante (decimal)Números com parte decimal1.65, 4.5, -0.25int e float
boolbooleano (lógico)Só dois valores: sim ou nãotrue, falseBooleanos
arrayarranjo (lista)Vários valores numa variável só["arroz", "feijão"]Arrays
objectobjetoDados e ações juntos, criados a partir de uma classenew DateTime()Classes e Objetos
nullnulo"Nenhum valor"nullnull
callable"chamável"Algo que pode ser chamado como uma função"strlen", fn($x) => $x * 2Funções Anônimas
resourcerecursoUma ligação com algo de fora: um arquivo aberto, uma conexãoo que fopen() devolveLer e Escrever Arquivos

Não precisa decorar. Os quatro primeiros (string, int, float, bool) são os tipos escalares: guardam um valor só, e são 90% do que você vai usar no Nível 1. array e object são tipos compostos: guardam vários valores dentro. null e resource são tipos especiais. E callable é mais uma "etiqueta" do que um tipo de verdade, como você vai ver abaixo.

Vendo todos de uma vez com var_dump

O var_dump mostra o tipo e o valor de qualquer coisa. É a ferramenta número um para estudar tipos (ele tem aula própria: var_dump e print_r):

<?php
$texto = "Ana";
$inteiro = 29;
$decimal = 1.65;
$logico = true;
$nada = null;
var_dump($texto, $inteiro, $decimal, $logico, $nada);
$ php tipos.php
string(3) "Ana"           « tipo string, 3 caracteres, valor "Ana"
int(29)                  « tipo int, valor 29
float(1.65)              « tipo float, valor 1.65
bool(true)               « tipo bool, valor true
NULL                     « null não tem valor para mostrar: só o tipo

Cada linha é tipo(valor). No caso da string, o número entre parênteses é o tamanho (em bytes; o porquê dos "bytes" está em Strings), e o valor vem depois, entre aspas.

Experimente: rode e confira os tipos. Depois troque os valores: o que o var_dump mostra para "29" (com aspas)? E para 29.0? E para "true"?

<?php
$a = 29;
$b = 1.65;
$c = "Ana";
$d = false;
var_dump($a, $b, $c, $d);

Um a um

string: texto

Qualquer texto entre aspas simples ou duplas: "Ana", 'Rua das Flores, 10', "42". Atenção ao último: com aspas, 42 é texto, não número. A string vazia, "", também é uma string (com zero caracteres). Aula: Strings.

int: número inteiro

Números sem vírgula, positivos ou negativos: 29, -5, 0, 1000000. Usado para contar coisas: quantidade, idade, ano. Aula: int e float.

float: número com casas decimais

Números com parte decimal, escritos com ponto: 1.65, 4.5. Também é float um número com ponto e zero: 10.0 aparece no var_dump como float(10). O nome vem de "ponto flutuante", a forma como o computador guarda esses números (e que tem umas surpresas, vistas em int e float).

bool: verdadeiro ou falso

Só existem dois valores: true (verdadeiro) e false (falso), sem aspas. São a resposta de perguntas como "a idade é maior que 18?" e de funções como isset. Aula: Booleanos.

array: vários valores juntos

Uma lista (ou tabela) de valores, entre colchetes:

<?php
$compras = ["arroz", "feijão"];
var_dump($compras);
$ php lista.php
array(2) {               « um array com 2 itens
  [0]=>                  « o item da posição 0 (a contagem começa no zero)…
  string(5) "arroz"       « …é uma string
  [1]=>
  string(7) "feijão"      « 7, e não 6: o "ã" ocupa 2 bytes
}

Arrays são tão importantes que têm um grupo inteiro de aulas, a partir de Arrays Indexados.

object: objeto

Um "pacote" com dados e ações, criado a partir de um molde chamado classe. O PHP já vem com várias classes prontas, como DateTime (para datas). O mais simples de todos é o stdClass ("classe padrão"), um objeto vazio onde você pendura dados:

<?php
$cliente = new stdClass();
$cliente->nome = "Ana";
var_dump($cliente);
$ php objeto.php
object(stdClass)#1 (1) {  « objeto da classe stdClass, o 1º criado, com 1 propriedade
  ["nome"]=>
  string(3) "Ana"
}

A seta -> acessa algo dentro do objeto. Objetos são o assunto do Nível 3; por enquanto, basta reconhecê-los.

null: nenhum valor

null é o tipo que tem um valor só: null, que quer dizer "nada aqui". É o que uma variável inexistente "vale" (com o Warning que você viu em Variáveis). Aula: null.

callable: algo que pode ser chamado

Em PHP, uma função pode ser guardada numa variável e chamada depois. "Callable" é o nome dado a qualquer coisa que pode ser chamada como função: o nome de uma função num texto ("strlen"), uma função anônima (fn($x) => $x * 2) e outras formas. Repare: "strlen" continua sendo do tipo string, e a função anônima é do tipo object. "Callable" descreve o que dá para fazer com eles, e a função is_callable pergunta isso:

<?php
$dobro = fn($x) => $x * 2;
var_dump($dobro(21));
var_dump(is_callable("strlen"), is_callable($dobro), is_callable("nao_existe"));
$ php chamavel.php
int(42)                  « $dobro(21) chamou a função guardada na variável
bool(true)               « "strlen" é o nome de uma função que existe
bool(true)
bool(false)              « não existe função chamada nao_existe

Aula: Funções Anônimas e Arrow Functions e Callables de Primeira Classe.

resource: uma ligação com o mundo de fora

Quando o PHP abre um arquivo, ele devolve um "recurso": um número de controle que representa o arquivo aberto. Você não cria recursos com as próprias mãos; eles vêm de funções como fopen:

<?php
$arquivo = fopen("php://memory", "r");
var_dump($arquivo);
$ php recurso.php
resource(5) of type (stream)   « recurso nº 5, do tipo "stream" (fluxo de dados)

(php://memory é um "arquivo" de mentirinha, guardado na memória.) Recursos aparecem em Ler e Escrever Arquivos. O PHP moderno tem trocado muitos recursos por objetos, então você vai vê-los cada vez menos.


Tipagem dinâmica: a caixa não tem tipo, o valor tem

Em linguagens como Java, você diz o tipo ao criar a variável (int idade = 29;), e ela só aceita aquele tipo para sempre. Em PHP, a variável não tem tipo; o valor dentro dela é que tem. Se você troca o valor, o tipo muda junto:

<?php
$x = 10;
echo get_debug_type($x), "\n";
$x = "dez";
echo get_debug_type($x), "\n";
$x = 10.5;
echo get_debug_type($x), "\n";
$x = false;
echo get_debug_type($x), "\n";
$ php dinamica.php
int
string
float
bool

Isso se chama tipagem dinâmica: o tipo é decidido enquanto o programa roda, olhando o valor. A vantagem é escrever menos. O cuidado é que o PHP não avisa se você guardar sem querer um texto onde esperava um número.

10 não é "10"

Com aspas, é texto; sem aspas, é número. O PHP mostra a diferença:

<?php
var_dump(10, "10", 10.0);
$ php dez.php
int(10)                  « número inteiro
string(2) "10"          « texto de 2 caracteres: o "1" e o "0"
float(10)                « número decimal (10.0)

Isso importa muito na web: tudo o que chega de um formulário é string, mesmo que o visitante tenha digitado um número. O PHP é tolerante e, numa conta, transforma "4.50" em número sozinho. Mas, se o texto não tiver cara de número, o programa para:

<?php
$preco = "4.50";
$qtd = 2;
var_dump($preco * $qtd);
var_dump("Ana" * 2);
$ php soma.php
float(9)                 « "4.50" virou 4.5 para a conta

Fatal error: Uncaught TypeError: Unsupported operand types: string * int in /home/ana/site/soma.php:5
Stack trace:
#0 {main}
  thrown in /home/ana/site/soma.php on line 5

TypeError = "erro de tipo"; Unsupported operand types: string * int = "tipos de operandos não suportados: string vezes int". Não dá para multiplicar "Ana". Essas transformações automáticas (e quando elas falham) são o assunto de Conversão de Tipos.


Descobrir o tipo: gettype e get_debug_type

O var_dump é ótimo para olhar, mas às vezes você quer o nome do tipo como texto, para mostrar ou comparar. O PHP tem duas funções para isso:

gettype($x)
"pegar o tipo". Existe desde sempre e devolve nomes antigos, alguns diferentes dos atuais.
get_debug_type($x) PHP 8.0+
"pegar o tipo para depuração". Devolve os nomes modernos, os mesmos que você escreve no código, e o nome da classe dos objetos.
<?php
$valores = ["Ana", 29, 1.65, true, ["arroz"], new DateTime(), null, fn($x) => $x, fopen("php://memory", "r")];
foreach ($valores as $v) {
    echo str_pad(gettype($v), 12), get_debug_type($v), "\n";
}

(O foreach repete a linha do echo para cada valor da lista; ele tem aula própria, foreach. O str_pad só completa o texto com espaços para alinhar as colunas.)

$ php nomes.php
string      string
integer     int                  « gettype diz "integer"
double      float                « gettype diz "double" (nome histórico)
boolean     bool
array       array
object      DateTime             « get_debug_type diz QUAL objeto
NULL        null
object      Closure              « a função anônima é um objeto da classe Closure
resource    resource (stream)
Valorgettypeget_debug_type
"Ana"stringstring
29integerint
1.65doublefloat
truebooleanbool
[...]arrayarray
objetoobjecto nome da classe (DateTime)
nullNULLnull
recursoresourceresource (stream)

Qual usar? Em código novo, get_debug_type: os nomes batem com os que você escreve no código e com os que aparecem nas mensagens de erro do PHP 8. Você vai ver gettype em código antigo; lembre que "double" é o float.

Missão: a Ana cadastrou uma cliente, mas guardou cada valor com o tipo errado. Troque só os valores (não mexa no echo) para que a saída seja string int float bool: o nome é texto, a idade é inteiro, a altura tem casas decimais e "ativa" é verdadeiro ou falso.

<?php
$nome = 29;
$idade = "29";
$altura = 1;
$ativa = "sim";
echo get_debug_type($nome), " ", get_debug_type($idade), " ",
     get_debug_type($altura), " ", get_debug_type($ativa), "\n";
<?php
$nome = "Bia";
$idade = 29;
$altura = 1.65;
$ativa = true;
echo get_debug_type($nome), " ", get_debug_type($idade), " ",
     get_debug_type($altura), " ", get_debug_type($ativa), "\n";

Testar o tipo: as funções is_*

Para perguntar "isto é de tal tipo?", use as funções que começam com is_ ("é"). Todas devolvem true ou false, prontas para usar num if:

FunçãoPerguntaExemplo que dá true
is_string($x)É texto?is_string("Ana")
is_int($x)É inteiro?is_int(29)
is_float($x)É decimal?is_float(1.65)
is_bool($x)É booleano?is_bool(false)
is_array($x)É array?is_array([])
is_object($x)É objeto?is_object(new stdClass())
is_null($x)É null?is_null(null)
is_callable($x)Dá para chamar como função?is_callable("strlen")
is_resource($x)É um recurso aberto?is_resource(fopen(...))
is_numeric($x)É número ou texto com cara de número?is_numeric("29")

As funções olham o tipo, não a aparência:

<?php
var_dump(is_int(29));
var_dump(is_int("29"));
var_dump(is_numeric("29"));
$ php is.php
bool(true)
bool(false)              « "29" com aspas é string, não int
bool(true)               « mas tem cara de número

Por isso, para conferir o que veio de um formulário (sempre string), use is_numeric, explicado em int e float, ou as funções de Validar Dados.


Dizer o tipo nas funções (só a ideia)

A tipagem dinâmica não impede você de exigir um tipo. Ao criar suas próprias funções, você pode escrever o tipo de cada entrada e da saída, e o PHP confere:

function dobro(int $n): int
{
    return $n * 2;
}

Aqui, int $n diz "esta função recebe um inteiro" e : int diz "e devolve um inteiro". Isso é chamado de declaração de tipos e é como se escreve PHP moderno. Você vai aprender em Tipos e Retorno e, com tipos mais elaborados (int|string, ?int, mixed), em Tipos Avançados.


Quando dá errado

Fatal error: Uncaught TypeError: Unsupported operand types
$ php soma.php
float(9)

Fatal error: Uncaught TypeError: Unsupported operand types: string * int in /home/ana/site/soma.php:5
Stack trace:
#0 {main}
  thrown in /home/ana/site/soma.php on line 5

O que significa: você fez uma conta com um valor que não é número nem texto com cara de número. A mensagem diz os tipos envolvidos (string * int) e a linha.

Como consertar: mostre o valor com var_dump logo antes da linha do erro para ver o que ele realmente é. Muitas vezes é uma variável que você achava que tinha um número e tem um nome, ou um array.

gettype devolveu double e o seu if não funcionou

O que significa: você comparou gettype($x) === "float", mas o gettype usa o nome antigo "double" (e "integer", "boolean").

Como consertar: use is_float($x), que é mais direto, ou get_debug_type($x) === "float".

is_int diz false para um número digitado no formulário

O que significa: o valor é a string "29"; is_int só aceita o tipo int.

Como consertar: use is_numeric para conferir e converta com (int) ou intval (veja Conversão de Tipos).


Referência rápida

Para…UseResultado
ver tipo e valorvar_dump($x)int(29)
nome do tipo (moderno)get_debug_type($x)"int", "float", "DateTime"
nome do tipo (antigo)gettype($x)"integer", "double"
testar um tipois_string, is_int, is_float, is_bool, is_array, is_object, is_nulltrue / false
número ou texto numérico?is_numeric($x)true para 29 e "29"
pode ser chamado?is_callable($x)true para "strlen"

Exercícios

1. O tipo moderno

Complete para mostrar float:

echo (1.65);

2. É texto?

Complete com a função que responde true para "Ana":

var_dump(("Ana"));

3. O que var_dump("42"); mostra?

4. Qual o resultado de gettype(1.5)?

5. O que significa dizer que o PHP tem "tipagem dinâmica"?

Missão final: o detetive de tipos

Missão: o programa já mostra o tipo de $a. Crie mais três variáveis: $b com uma lista de compras (um array), $c com null e $d com false. Mostre o tipo de cada uma com get_debug_type, uma por linha. A saída deve ter array, null e bool.

<?php
$a = "Ana";
echo get_debug_type($a), "\n";
<?php
$a = "Ana";
echo get_debug_type($a), "\n";
$b = ["arroz", "feijão"];
$c = null;
$d = false;
echo get_debug_type($b), "\n";
echo get_debug_type($c), "\n";
echo get_debug_type($d), "\n";

Resumo

  • Todo valor tem um tipo, e o tipo decide o que dá para fazer com ele.
  • Escalares: string (texto), int (inteiro), float (decimal, com ponto), bool (true/false). Compostos: array, object. Especiais: null, resource. E callable: o que pode ser chamado como função.
  • Tipagem dinâmica: a variável não tem tipo; o valor tem. 10, "10" e 10.0 são três coisas diferentes.
  • var_dump mostra tipo e valor; get_debug_type dá o nome moderno do tipo; gettype dá o antigo ("double", "integer").
  • is_int, is_string… testam o tipo; is_numeric aceita texto com cara de número.