PHP Booleanos

"O cliente está logado?" "Tem o produto no estoque?" "A senha está certa?" Perguntas assim só têm duas respostas: sim ou não. Em programação, a resposta sim/não é um valor do tipo booleano (bool), que só pode ser true (verdadeiro) ou false (falso). Nesta aula você aprende de onde vêm esses valores e uma regra do PHP que pega muita gente: na hora de decidir, quase qualquer valor pode ser tratado como verdadeiro ou falso, inclusive o texto "0".

Você vai aprender
  • O que são true e false e onde eles aparecem.
  • Por que echo true mostra 1 e echo false não mostra nada.
  • A lista completa do que o PHP considera falso (com o resultado real de cada um).
  • A armadilha da string "0", e como fugir dela.

Os programas desta aula rodaram com o PHP 8.5 na máquina fictícia da Ana, na pasta ~/site. Os booleanos são o "combustível" das decisões (if, elseif, else) e das repetições (while); aqui você entende o valor em si.


A ideia: um interruptor

Um interruptor de luz tem duas posições: ligado ou desligado. Não existe "meio ligado". Um booleano é isso: um valor com só duas posições. O nome vem do matemático inglês George Boole, que criou, no século XIX, a "álgebra" do verdadeiro e falso que todo computador usa.

<?php
$logado = true;
$temEstoque = false;
var_dump($logado, $temEstoque);
$ php interruptor.php
bool(true)
bool(false)
true
"Verdadeiro". Escrito sem aspas: "true" com aspas é uma string de 4 letras.
false
"Falso". Também sem aspas.
bool(true)
O var_dump mostra o tipo bool e o valor.

O PHP aceita true, TRUE e True (as palavras da linguagem não diferenciam maiúsculas), mas o costume moderno é sempre em minúsculas. Bons nomes para variáveis booleanas parecem perguntas de sim/não: $logado, $temEstoque, $ehAdmin, $podeComprar.


1. De onde vêm os booleanos

Você raramente escreve true ou false à mão. Na maior parte do tempo, eles são a resposta de uma pergunta que o programa faz:

<?php
var_dump(5 > 3);
var_dump(5 < 3);
var_dump("Ana" === "Ana");
var_dump(isset($cupom));
var_dump(is_int(29));
$ php perguntas.php
bool(true)               « 5 é maior que 3?
bool(false)              « 5 é menor que 3?
bool(true)               « "Ana" é idêntico a "Ana"?
bool(false)              « $cupom existe?
bool(true)               « 29 é um int?
De onde vemExemploAula
Comparações$idade >= 18, $senha === "abc"Comparação
Combinações de perguntas$logado && $temEstoqueOperadores Lógicos
Funções que respondem sim/nãoisset, is_int, in_array, file_existsvárias
Escritos à mão$modoTeste = true;esta

2. Mostrar um booleano: o echo engana

Experimente mostrar um booleano com echo:

<?php
echo "echo true: [", true, "]\n";
echo "echo false: [", false, "]\n";
$ php echo-bool.php
echo true: [1]           « true vira o texto "1"
echo false: []           « false vira o texto vazio: não aparece nada!

O echo só sabe mostrar texto, então converte o booleano: true vira "1" e false vira "" (string vazia). Os colchetes no exemplo estão lá só para você ver que não saiu nada no lugar do false. Por isso, para investigar um booleano, use sempre o var_dump. Se precisar escrever a palavra, use var_export($x, true) ou json_encode($x), que devolvem "true" / "false" (veja var_dump e print_r).


3. O que conta como falso

Quando o PHP precisa de um booleano e recebe outro tipo (no if, no while, no !, no &&), ele converte o valor. A regra é curta: existe uma lista pequena de valores que viram false; todo o resto vira true.

Para ver a conversão, use (bool) na frente do valor: é o cast, a conversão explícita (aula Conversão de Tipos).

<?php
var_dump((bool) false);
var_dump((bool) 0);
var_dump((bool) 0.0);
var_dump((bool) -0.0);
var_dump((bool) "");
var_dump((bool) "0");
var_dump((bool) []);
var_dump((bool) null);
$ php falsos.php
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)

Esses são todos os valores falsos do PHP. Decore esta tabela: ela vale para a linguagem inteira.

ValorTipo(bool)Comentário
falseboolfalseo próprio
0intfalseo inteiro zero
0.0, -0.0floatfalseo float zero
""stringfalsea string vazia
"0"stringfalsea armadilha: o texto com um zero
[]arrayfalseo array vazio
nullnullfalse"nenhum valor" (e variáveis inexistentes)

E o que é verdadeiro: todo o resto

Qualquer valor fora da lista vira true, inclusive alguns que "parecem" falsos:

<?php
var_dump((bool) 1);
var_dump((bool) -1);
var_dump((bool) 0.1);
var_dump((bool) "a");
var_dump((bool) " ");
var_dump((bool) "0.0");
var_dump((bool) "00");
var_dump((bool) "false");
var_dump((bool) [0]);
var_dump((bool) new stdClass());
$ php verdadeiros.php
bool(true)               « 1
bool(true)               « -1: negativo não é zero
bool(true)               « 0.1
bool(true)               « "a"
bool(true)               « " ": um espaço já não é string vazia
bool(true)               « "0.0": só o texto "0" exato é falso
bool(true)               « "00"
bool(true)               « "false": é uma string de 5 letras!
bool(true)               « [0]: array com um item (mesmo que o item seja 0)
bool(true)               « qualquer objeto

Experimente: troque o valor de $valor e tente adivinhar o resultado antes de rodar. Teste "0", "0.0", " ", [], [[]], -5, "no", null.

<?php
$valor = "0";
var_dump((bool) $valor);
Novidade do PHP 8.5: NAN

O valor especial NAN ("não é um número", visto em int e float) vira true, mas o PHP 8.5 passou a avisar, porque isso quase sempre indica um erro de conta:

$ php nan.php                « var_dump((bool) NAN);

Warning: unexpected NAN value was coerced to bool in /home/ana/site/nan.php on line 2
bool(true)

Coerced to bool = "forçado a virar bool".


4. A armadilha da string "0"

Por que o PHP trata "0" como falso? Porque, na web, tudo chega como texto. Se um formulário pergunta "quantos itens?" e o visitante digita 0, o PHP recebe a string "0". Tratar "0" como o número zero (falso) foi pensado para ajudar. Só que, às vezes, "0" é um texto legítimo:

<?php
$apelido = "0";
if ($apelido) {
    echo "Olá, $apelido\n";
} else {
    echo "Apelido vazio!\n";
}
$ php armadilha.php
Apelido vazio!           « a cliente digitou "0" e o programa achou que estava vazio

(O if executa o primeiro bloco quando a condição é verdadeira e o bloco do else quando é falsa; os detalhes estão em if, elseif, else.)

O if ($apelido) pergunta "o apelido, convertido para bool, é verdadeiro?". E "0" vira false. O conserto é perguntar exatamente o que você quer saber: "o apelido é diferente da string vazia?":

if ($apelido !== "") {      // "é diferente de vazio?"  →  "0" passa
Você quer saber…Pergunte assimCom "0" dá
A string tem algum caractere?$s !== "" ou strlen($s) > 0true ✔
A variável existe e não é null?isset($s)true ✔
O valor é "verdadeiro" pela regra do PHP?if ($s)false ✘
O empty cai na mesma armadilha

A função empty($x) ("está vazio?") é o contrário da conversão para bool, e ainda não reclama de variável inexistente. Ela devolve true para todos os valores falsos da tabela, inclusive "0":

$ php empty.php             « var_dump(empty("0"), empty(""), empty("a"), empty($naoExiste));
bool(true)                  « "0" é considerado vazio!
bool(true)
bool(false)
bool(true)                  « variável inexistente: vazio, sem Warning

Use empty com cuidado em campos de texto que podem receber "0" (apelido, número da casa, nota de prova).

E o texto "false", "sim", "não"?

Um formulário ou arquivo de configuração pode mandar "false" como texto. Como você viu, (bool) "false" é true. Para interpretar palavras, use filter_var($x, FILTER_VALIDATE_BOOLEAN), que entende "true", "false", "yes", "no", "on", "off", "1" e "0", em inglês ("sim" dá false). Detalhes em Validar Dados.


5. Booleanos em contas

Se você usar um booleano numa conta, ele vira número: true é 1 e false é 0. true + true dá int(2). Funciona, mas evite: quem lê o código não espera contas com verdadeiro e falso.


Quando dá errado

O echo de uma variável não mostra nada

O que significa: a variável provavelmente vale false (ou null, ou ""), e o echo mostra todos eles como "nada".

Como consertar: troque o echo por var_dump para ver o tipo e o valor real.

Um valor "0" foi tratado como vazio

O que significa: o código usa if ($x), if (!$x) ou empty($x), e "0" é falso no PHP.

Como consertar: pergunte exatamente o que quer: $x !== "", $x !== null, isset($x).

"false" foi tratado como verdadeiro

O que significa: o valor é a string "false", que não está na lista dos falsos.

Como consertar: escreva false sem aspas, ou converta o texto com filter_var($x, FILTER_VALIDATE_BOOLEAN).


Referência rápida

EscritaO que fazExemplo → resultado
true, falseOs dois valores booleanosbool(true)
(bool) $x, boolval($x)Converte para bool(bool) "0" → false
is_bool($x)É do tipo bool?is_bool(0) → false
empty($x)Não existe ou é falso?empty("0") → true
echo true / echo falseMostra 1 / nada
var_export($x, true)A palavra true/false"false"
Falsosfalse, 0, 0.0, -0.0, "", "0", [], null

Exercícios

1. Converter

Complete para converter $x em booleano:

var_dump(() $x);

2. O texto do verdadeiro

Complete com o que aparece na tela quando o PHP roda echo true;:

echo true;  → 

3. Qual destes valores é verdadeiro para o PHP?

4. O que var_dump((bool) "false"); mostra?

5. A variável $numeroCasa veio de um formulário com o texto "0". Qual teste responde "o campo foi preenchido?" corretamente?

Missão final: o apelido "0"

Missão: a cliente escolheu o apelido "0", mas o programa responde Apelido vazio!. Mude só a condição do if para que qualquer texto não vazio seja aceito, inclusive "0". A saída deve ser Olá, 0. Depois teste com $apelido = "";: deve voltar a aparecer Apelido vazio!.

<?php
$apelido = "0";
if ($apelido) {
    echo "Olá, $apelido\n";
} else {
    echo "Apelido vazio!\n";
}
<?php
$apelido = "0";
if ($apelido !== "") {
    echo "Olá, $apelido\n";
} else {
    echo "Apelido vazio!\n";
}

Resumo

  • Booleano (bool) tem dois valores: true e false, sem aspas.
  • Eles vêm de comparações (5 > 3), de funções (isset, is_int) e das combinações com &&, ||, !.
  • echo true mostra 1; echo false não mostra nada. Investigue com var_dump.
  • São falsos: false, 0, 0.0, -0.0, "", "0", [], null. Todo o resto é verdadeiro (inclusive " ", "0.0" e "false").
  • Cuidado com "0": em if ($x) e empty($x) ele conta como vazio. Pergunte exatamente o que quer ($x !== "").