Nesta aula, vamos explorar os operadores em PHP, fundamentais para manipular dados e controlar o fluxo dos programas. Os operadores são símbolos que realizam operações em variáveis e valores, como somar números, comparar strings ou combinar condições booleanas. Dominar os operadores é essencial para escrever código eficiente e expressivo.

Começaremos com os operadores clássicos (aritméticos, comparação e lógicos), depois veremos as diferenças entre comparação solta e estrita, e em seguida abordaremos operadores modernos que tornam o código mais conciso e seguro. Por fim, apresentaremos o operador spaceship, um aliado em ordenações.

Aritméticos, comparação, lógicos

Os operadores aritméticos realizam operações matemáticas básicas: adição (+), subtração (-), multiplicação (*), divisão (/), módulo (%), exponenciação (**) e negação (-). Eles funcionam como na matemática, mas com algumas particularidades em PHP, como a divisão sempre retornar float se o resultado não for inteiro.

$a = 10;
$b = 3;
echo $a + $b;  // 13
echo $a - $b;  // 7
echo $a * $b;  // 30
echo $a / $b;  // 3.3333333333333
echo $a % $b;  // 1 (resto da divisão)
echo $a ** $b; // 1000 (10³)
echo -$a;      // -10

Operadores de comparação comparam dois valores e retornam um booleano. São eles: igual (==), idêntico (===), diferente (!=, <>), não idêntico (!==), menor que (<), maior que (>), menor ou igual (<=), maior ou igual (>=) e o operador spaceship (<=>) que veremos adiante. Exemplos:

var_dump(5 == "5");   // bool(true)
var_dump(5 === "5");  // bool(false)
var_dump(5 != "5");   // bool(false)
var_dump(5 !== "5");  // bool(true)
var_dump(5 < 10);     // bool(true)
var_dump(5 >= 5);     // bool(true)

Operadores lógicos permitem combinar expressões booleanas: and (&&), or (||), not (!), xor (xor). Eles seguem as regras da lógica proposicional. Exemplo:

$idade = 25;
$temCarteira = true;
if ($idade >= 18 && $temCarteira) {
    echo "Pode dirigir";
}
$logado = false;
if (!$logado) {
    echo "Faça login";
}

== vs ===

A diferença entre == (igualdade) e === (identidade) é crucial em PHP para evitar bugs sutis. O operador == compara valores após a conversão de tipos (type juggling), enquanto === compara valor e tipo sem conversão. Isso significa que expressões como 0 == "0" retornam true, mas 0 === "0" retorna false porque um é inteiro e outro é string.

Outro exemplo clássico: "" == false retorna true, mas "" === false retorna false. Por isso, sempre que possível, prefira === para comparações mais previsíveis e seguras. A conversão automática de tipos pode levar a resultados inesperados, especialmente em funções como in_array() que possuem um terceiro parâmetro strict.

var_dump(0 == "0");   // true
var_dump(0 === "0");  // false
var_dump(false == ""); // true
var_dump(false === ""); // false
var_dump(null == "");  // true
var_dump(null === ""); // false

Operadores modernos (??, ?:, ?->)

O PHP moderno introduziu operadores que simplificam verificações comuns. O operador null coalescing (??) retorna o primeiro operando se ele não for null; caso contrário, retorna o segundo. É útil para fornecer valores padrão sem usar isset(). Exemplo:

$nome = $_GET['nome'] ?? 'Visitante';
echo $nome; // Se 'nome' não existir, exibe 'Visitante'

O operador ternário (? :) é uma forma concisa de if-else. A expressão (condição) ? valor_se_verdadeiro : valor_se_falso. Exemplo:

$idade = 18;
$podeVotar = ($idade >= 16) ? 'Sim' : 'Não';
echo $podeVotar; // Sim

Desde o PHP 8, temos o operador nullsafe (?->) que permite chamar métodos ou acessar propriedades em uma cadeia sem verificar se cada parte é null. Se algum elo for null, a expressão inteira retorna null sem gerar erro. Exemplo:

$usuario = null;
$cidade = $usuario?->endereco?->cidade;
var_dump($cidade); // NULL, sem erro

Spaceship

O operador spaceship (<=>) é um operador de comparação de três vias introduzido no PHP 7. Ele retorna -1, 0 ou 1 dependendo se o primeiro operando é menor, igual ou maior que o segundo. É especialmente útil em funções de ordenação como usort().

echo 1 <=> 2; // -1
echo 2 <=> 2; // 0
echo 3 <=> 2; // 1

// Ordenando um array de forma ascendente:
$arr = [3, 1, 2];
usort($arr, fn($a, $b) => $a <=> $b);
print_r($arr); // [1, 2, 3]

Boas práticas

Ao usar operadores, lembre-se de: prefira === sobre == para evitar conversões automáticas; use ?? para valores padrão em vez de isset() com ternário; utilize ?-> para cadeias opcionais; e spaceship para ordenações simples. Essas práticas tornam o código mais legível e menos propenso a erros.

Exercícios

  1. Qual é a saída do código abaixo?

    var_dump(0 == "a");
    var_dump(0 === "a");

    ✓ Resposta: A primeira linha exibe bool(true), pois 0 é convertido para string vazia e comparado com "a" (que também é convertido para 0). A segunda exibe bool(false), pois os tipos são diferentes (int vs string).
  2. Escreva uma expressão usando ?? que atribua 'padrão' a $valor se $_GET['id'] não existir ou for null.

    ✓ Resposta:
    $valor = $_GET['id'] ?? 'padrão';
  3. O que o operador ?-> retorna se a expressão for null? Dê um exemplo.

    ✓ Resposta: Retorna null. Exemplo: $obj?->metodo() retorna null se $obj for null, sem lançar erro.
  4. Ordene o array [5, 3, 8, 1] de forma decrescente usando o operador spaceship.

    ✓ Resposta:
    $arr = [5, 3, 8, 1];
    usort($arr, fn($a, $b) => $b <=> $a);
    print_r($arr); // [8, 5, 3, 1]
  5. Explique a diferença entre os operadores ternário (? :) e null coalescing (??) com exemplos.

    ✓ Resposta: O ternário avalia uma condição booleana; o ?? verifica se o valor é null. Exemplo: $x = $cond ? 'sim' : 'não'; vs $y = $valor ?? 'padrão';. O ?? não aceita condição, apenas verifica null.

Referências