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?".
- Os tipos do PHP:
string,int,float,bool,array,object,null,callableeresource. - O que é tipagem dinâmica e por que
10e"10"não são a mesma coisa. - Como descobrir o tipo de um valor com
var_dump,gettypeeget_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 * 2dá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
| Tipo | Nome em português | Guarda | Exemplos | Aula |
|---|---|---|---|---|
string | texto ("cadeia de caracteres") | Letras, palavras, frases | "Ana", 'maçã', "" | Strings |
int | inteiro | Números sem parte decimal | 29, -5, 0 | int e float |
float | ponto flutuante (decimal) | Números com parte decimal | 1.65, 4.5, -0.25 | int e float |
bool | booleano (lógico) | Só dois valores: sim ou não | true, false | Booleanos |
array | arranjo (lista) | Vários valores numa variável só | ["arroz", "feijão"] | Arrays |
object | objeto | Dados e ações juntos, criados a partir de uma classe | new DateTime() | Classes e Objetos |
null | nulo | "Nenhum valor" | null | null |
callable | "chamável" | Algo que pode ser chamado como uma função | "strlen", fn($x) => $x * 2 | Funções Anônimas |
resource | recurso | Uma ligação com algo de fora: um arquivo aberto, uma conexão | o que fopen() devolve | Ler 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)
| Valor | gettype | get_debug_type |
|---|---|---|
"Ana" | string | string |
29 | integer | int |
1.65 | double | float |
true | boolean | bool |
[...] | array | array |
| objeto | object | o nome da classe (DateTime) |
null | NULL | null |
| recurso | resource | resource (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ção | Pergunta | Exemplo 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… | Use | Resultado |
|---|---|---|
| ver tipo e valor | var_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 tipo | is_string, is_int, is_float, is_bool, is_array, is_object, is_null | true / 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:
2. É texto?
Complete com a função que responde true para "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. Ecallable: o que pode ser chamado como função. - Tipagem dinâmica: a variável não tem tipo; o valor tem.
10,"10"e10.0são três coisas diferentes. var_dumpmostra tipo e valor;get_debug_typedá o nome moderno do tipo;gettypedá o antigo ("double","integer").is_int,is_string… testam o tipo;is_numericaceita texto com cara de número.