A evolução da comparação ternária no PHP
7 years ago by Jaime NetoO PHP vem evoluindo muito desde sua criação, principalmente nas últimas versões, que vêm incorporando os mais modernos conceitos no que diz respeito ao desenvolvimento de software. Uma das funcionalidades básicas, e que também vem trazendo evoluções, é o operador ternário. Vamos dar uma olhada nas formas que temos de utilizá-lo e entender a diferença entre elas.
Digamos que temos a seguinte comparação:
if ($a) {
$resultado = 'a';
} else {
$resultado = 'b';
}
Podemos fazer a mesma coisa, utilizando o operador ternário a seguir:
$resultado = $a ? 'a' : 'b';
Ok. Isso já serve pra economizar algumas linhas de código, e deixá-lo mais objetivo e rápido. Mas, dependendo do caso, pode ainda ser mais encurtado. Digamos que agora eu queira algo como o caso abaixo:
$resultado = $a ? $a : 'b';
Existe, desde o PHP 5.3 uma forma mais curta de fazer essa mesma comparação:
$resultado = $a ?: 'b';
Com isso já conseguimos economizar um pouco mais de código. Mas ainda existe um pequeno problema nessa abordagem: ela só funciona bem, se eu tiver certeza que $a
existe, pois o operador não faz esse teste, e se $a
não existir, será gerado um mensagem de NOTICE dizendo que a variável não foi declarada. Ele funciona muito bem, por exemplo, dentro de uma função:
function teste($a) {
return $a ?: 'b';
}
Mas, caso eu precise testar se $a foi declarado, ou seja, se o que eu quero é o equivalente ao código abaixo:
$resultado = isset($a) ? $a : 'b';
Eu ainda posso usar o operador de coalescência nula, ou operador ??
, que foi criado no PHP 7:
$resultado = $a ?? 'b';
Essa é uma forma muito prática, e muito útil, principalmente se você quer utilizar algo que foi passado como parâmetro na requisição, como $_GET
ou $_POST
, e queria definir um valor padrão, caso o parâmetro não tenha sido passado. Veja o exemplo:
$user = $_GET['user'] ?? 'guest';
Mas então, você pode estar se perguntando pra que ainda existe o operador ?:
se o ??
já resolve, não é? Bem, perceba que, no primeiro exemplo, o ??
não verifica se $a
é verdadeiro, ele apenas verifica se ele foi declarado e não é nulo. Veja como o resultado seria diferente nos seguintes casos:
$a = 0;
$resultado = $a ?: 'b'; // retorna 'b'
$resultado = $a ?? 'b'; // retorna 0
Ou seja, ?:
testou se $a
é um valor válido e não vazio, enquanto ??
testou apenas se $a
foi declarado e não é nulo, independente de seu valor. É preciso tomar muito cuidado com isso, levando em conta o que você queira que seja testado.
Uma outra coisa muito interessante desses operadores ?:
e ??
é a possibilidade de concatenar os testes, simplificando e encurtando ainda mais o código:
$resultado = $a ?? $b ?? $c ?? 'd';
Esse código, se usado com o operador ternário comum, equivaleria a:
$resultado = isset($a) && $a !== null ? $a
: (isset($b) && $b !== null ? $b
: (isset($c) && $c !== null ? $c : 'd'));
Ou, usando ifs:
if (isset($a) && $a !== null) {
$resultado = $a;
} elseif (isset($b) && $b !== null) {
$resultado = $b;
} elseif (isset($c) && $c !== null) {
$resultado = $c;
} else {
$resultado = 'd';
}
E aí, qual a melhor forma? ^__^