PHP null
No cadastro da lojinha, a Ana pede o telefone dos clientes, mas o campo é opcional. Como guardar "este cliente não informou o telefone"? Não é o número zero, nem um texto vazio: é a ausência de valor. Para isso, o PHP tem um valor especial, null ("nulo"), que quer dizer exatamente "nada aqui". Nesta aula você aprende o que é null, de onde ele aparece sem você pedir, como testá-lo e por que ele não é a mesma coisa que "" e 0.
- O que é
nulle como escrevê-lo. - Os lugares onde o
nullaparece sozinho (variável inexistente, chave que não existe, função semreturn). - Como testar:
is_null,=== nulleisset. - A diferença entre
null,""(texto vazio) e0(zero). - O atalho
??para "use isto, ou um valor padrão se for null". - Os avisos e erros de usar
nullonde o PHP esperava outra coisa.
Os programas desta aula rodaram com o PHP 8.5 na máquina fictícia da Ana, na pasta ~/site.
A ideia: o campo em branco que ninguém preencheu
Pense em três clientes da Ana e na pergunta "quantos filhos você tem?":
- A Bia respondeu 0. Ela tem zero filhos: é uma resposta, um número.
- O Caio apagou o que tinha escrito e deixou o campo em branco: ele respondeu, com um texto vazio.
- A Duda nunca viu a pergunta: o formulário antigo não tinha esse campo. Não existe resposta.
Em PHP, a resposta da Bia é 0 (int), a do Caio é "" (string vazia) e a da Duda é null. Três coisas diferentes. null é o único valor que diz "não há valor nenhum aqui".
1. Escrever e mostrar null
<?php $telefone = null; var_dump($telefone); echo "[", $telefone, "]\n"; var_dump(get_debug_type($telefone));
$ php nulo.php NULL « o var_dump mostra só o tipo: não há valor para mostrar [] « o echo não mostra nada string(4) "null" « o tipo se chama null
- null
- A palavra que representa "nenhum valor". Sem aspas:
"null"com aspas seria um texto de 4 letras. O PHP aceitaNULLeNulltambém; o costume moderno énullem minúsculas. - NULL (no var_dump)
- O
var_dumpescreve em maiúsculas, por tradição. É o mesmo valor. - []
- Para o
echo,nullvira texto vazio, como ofalse(aula Booleanos). Por isso, investigue sempre comvar_dump.
null é ao mesmo tempo um tipo e o único valor desse tipo: o tipo null só tem um valor possível (veja Tipos de Dados).
2. De onde vem o null
Você pode escrever null de propósito, mas muitas vezes ele aparece sozinho:
| Situação | Exemplo | Aviso? |
|---|---|---|
| Atribuição de propósito | $telefone = null; | Não |
| Variável que não existe | var_dump($naoExiste); | Warning: Undefined variable |
| Chave de array que não existe | $lista["b"] | Warning: Undefined array key |
| Função que não devolve nada | uma função sem return | Não |
| Dados de fora (JSON, banco de dados) | {"telefone": null} | Não |
<?php
var_dump($naoExiste);
$lista = ["a" => 1];
var_dump($lista["b"]);
function semRetorno() { $a = 1; }
var_dump(semRetorno());
$ php origens.php Warning: Undefined variable $naoExiste in /home/ana/site/origens.php on line 2 NULL « a variável não existe: vale null, com aviso Warning: Undefined array key "b" in /home/ana/site/origens.php on line 4 NULL « o array não tem a chave "b": null, com aviso NULL « a função não tem return: devolve null
Os dois avisos são sinais de um provável erro de digitação ou de lógica (você vai entender os arrays em Arrays Associativos e as funções em Funções). Já o null da função sem return vem quieto. É por isso que é bom saber que ele existe.
3. Testar se é null
Há três formas de perguntar. Duas são equivalentes; a terceira é parecida, mas não igual:
<?php $telefone = null; var_dump(is_null($telefone)); var_dump($telefone === null); var_dump(isset($telefone));
$ php testar.php bool(true) « é null? bool(true) « é idêntico a null? bool(false) « existe e NÃO é null?
- is_null($x)
- "É nulo?". Função que devolve
truese o valor énull. - $x === null
- "É idêntico a null?". Faz o mesmo com o operador de comparação estrita (aula Comparação). É a forma mais usada em código moderno.
- isset($x)
- "Está definida?". É o contrário:
truese existe e não énull. E tem um superpoder: não dá Warning quando a variável não existe (aula Variáveis).
A diferença aparece quando a variável nem existe:
<?php var_dump(is_null($naoExiste)); var_dump(isset($naoExiste));
$ php inexistente.php Warning: Undefined variable $naoExiste in /home/ana/site/inexistente.php on line 2 bool(true) « is_null reclama, depois responde bool(false) « isset responde em silêncio
Qual usar? Se a variável com certeza existe e você quer saber se é null: === null (ou is_null). Se ela pode nem existir (um campo de formulário, uma chave de array): isset.
Experimente: troque o valor de $telefone por "", 0, "0" e "99999-1234". Em quais casos is_null dá true? E isset? Depois apague a linha 2 inteira e rode de novo.
<?php $telefone = null; var_dump(is_null($telefone)); var_dump(isset($telefone));
4. null, "" e 0 não são a mesma coisa
Voltando às três clientes. Veja como cada teste responde para cada uma:
<?php $duda = null; // não respondeu $caio = ""; // respondeu em branco $bia = 0; // respondeu zero var_dump(is_null($duda), is_null($caio), is_null($bia)); var_dump(isset($duda), isset($caio), isset($bia)); var_dump(empty($duda), empty($caio), empty($bia));
$ php tres.php bool(true) « is_null: só a Duda bool(false) bool(false) bool(false) « isset: Caio e Bia "existem" bool(true) bool(true) bool(true) « empty: os três parecem "vazios"! bool(true) bool(true)
null | "" | 0 | |
|---|---|---|---|
| Quer dizer | não há valor | texto sem caracteres | o número zero |
| Tipo | null | string | int |
is_null / === null | true | false | false |
isset | false | true | true |
empty / (bool) é falso | sim | sim | sim |
echo mostra | nada | nada | 0 |
A lição: empty e o if ($x) jogam os três no mesmo saco, porque os três são "falsos" (aula Booleanos). Quando a diferença importa, pergunte com === null, === "" ou === 0.
== (dois iguais)
A comparação "frouxa" == converte os tipos antes de comparar, e acha que null é igual a "", a 0 e a false:
$ php frouxo.php « var_dump(null == "", null == 0, null == false, null === "", null === 0); bool(true) bool(true) bool(true) bool(false) « com três iguais, só null é idêntico a null bool(false)
Use sempre ===. A explicação completa está em Comparação (== e ===).
5. Valor padrão com ??
Muito do trabalho com null é "se não tiver valor, use um padrão". O PHP tem um operador só para isso, o ?? (chamado null coalescing, "união com nulo"):
<?php $nome = null; echo "Olá, " . ($nome ?? "visitante") . "\n"; $nome = "Ana"; echo "Olá, " . ($nome ?? "visitante") . "\n";
$ php padrao.php Olá, visitante « $nome é null: usa o padrão Olá, Ana « $nome tem valor: usa o valor
Leia $nome ?? "visitante" como "$nome, ou, se for null (ou nem existir), "visitante"". Como o isset, ele não dá Warning para variável inexistente. Repare que o ?? só olha o null: um 0 ou um "" passam direto. O ??, o ??= e o ?-> estão explicados em ?? e ?->.
6. null onde o PHP esperava outra coisa
O que acontece quando um null "escapa" e entra numa conta, numa função ou num objeto? Depende do lugar:
<?php var_dump(null + 5); var_dump(null . "abc"); var_dump(strlen(null));
$ php escapou.php int(5) « na conta, null vale 0 string(3) "abc" « no texto, null vale "" Deprecated: strlen(): Passing null to parameter #1 ($string) of type string is deprecated in /home/ana/site/escapou.php on line 4 int(0)
A última linha mostra um Deprecated ("obsoleto"): passar null para uma função do PHP que espera texto ainda funciona, mas foi marcado para deixar de funcionar numa versão futura. Passing null to parameter #1 ($string) of type string = "passando null para o parâmetro nº 1 ($string), que é do tipo string". Corrija sempre que aparecer.
Com objetos (assunto do Nível 3), o null é mais grave:
<?php $cliente = null; echo $cliente->nome; echo "\nfim\n"; echo $cliente->getNome();
$ php objeto-nulo.php
Warning: Attempt to read property "nome" on null in /home/ana/site/objeto-nulo.php on line 3
fim
Fatal error: Uncaught Error: Call to a member function getNome() on null in /home/ana/site/objeto-nulo.php:5
Stack trace:
#0 {main}
thrown in /home/ana/site/objeto-nulo.php on line 5
Ler uma propriedade de null dá Warning (Attempt to read property "nome" on null = "tentativa de ler a propriedade nome em null"); chamar um método em null é fatal (Call to a member function getNome() on null = "chamada de um método getNome() em null"). Esse é um dos erros mais comuns do PHP. O operador ?-> (?? e ?->) foi criado para ele.
Quando dá errado
Deprecated: ...: Passing null to parameter #1 ($string) of type string is deprecated
O que significa: uma variável que você passou para uma função (como strlen, trim, htmlspecialchars) valia null. Ainda funciona, mas vai virar erro no futuro.
Como consertar: descubra por que a variável é null (campo não enviado? chave errada?) ou dê um padrão: strlen($nome ?? "").
Fatal error: Uncaught Error: Call to a member function ...() on null
O que significa: a variável antes da seta -> deveria ter um objeto, mas tem null. Típico de uma busca que não encontrou nada ("busque o cliente 42" e o cliente não existe).
Como consertar: teste com if ($cliente === null) antes, ou use ?->.
Warning: Undefined array key "..." seguido de um NULL
O que significa: você pediu uma chave que o array não tem, e recebeu null.
Como consertar: confira o nome da chave, ou use $lista["b"] ?? "padrão" quando a chave pode mesmo faltar.
0 ou "" foi tratado como "não informado"
O que significa: o código testou com empty ou if (!$x), que juntam null, "" e 0.
Como consertar: teste só o null: $x === null.
Referência rápida
| Escrita | O que faz | Com null |
|---|---|---|
$x = null; | Guarda "nenhum valor" | |
is_null($x) | É null? | true (Warning se $x não existe) |
$x === null | É idêntico a null? | true |
isset($x) | Existe e não é null? | false (sem Warning) |
$x ?? $padrao | $x, ou o padrão se for null/inexistente | o padrão |
unset($x); | Apaga a variável (depois, ela "vale" null) | |
var_dump($x) | Mostra | NULL |
Exercícios
1. Testar null
Complete com o operador de comparação estrita:
2. Valor padrão
Complete para mostrar "sem e-mail" quando $email for null:
3. Qual o resultado de isset($x) depois de $x = 0;?
4. Uma função sem return devolve…
5. O que var_dump(null == 0); mostra?
Missão final: a ficha do cliente
Missão: a ficha mostra Telefone: em branco porque o telefone é null. Use o ?? para mostrar não informado no lugar de qualquer campo null. Atenção: Filhos: 0 deve continuar mostrando o zero (ele é uma resposta!).
Nome: Duda Telefone: não informado Filhos: 0
<?php $nome = "Duda"; $telefone = null; $filhos = 0; echo "Nome: " . $nome . "\n"; echo "Telefone: " . $telefone . "\n"; echo "Filhos: " . $filhos . "\n";
<?php $nome = "Duda"; $telefone = null; $filhos = 0; echo "Nome: " . ($nome ?? "não informado") . "\n"; echo "Telefone: " . ($telefone ?? "não informado") . "\n"; echo "Filhos: " . ($filhos ?? "não informado") . "\n";
Resumo
null= "nenhum valor". É um tipo com um valor só. Escreva sem aspas.- Aparece sozinho: variável inexistente e chave inexistente (com Warning), função sem
return, dados de JSON e banco. - Teste com
=== nullouis_null; useissetquando a variável pode nem existir. null,""e0são diferentes, masempty,if ($x)e==os confundem. Prefira===.$x ?? "padrão"dá um valor padrão quando$xé null.nullnuma função que espera texto dáDeprecated; chamar método emnulldáFatal error.