Condicionais: if, else, elseif, switch e match

1. Introdução às Estruturas Condicionais em PHP

As estruturas condicionais são o coração do controle de fluxo em qualquer linguagem de programação. Em PHP, elas permitem que seu código tome decisões baseadas em condições específicas, executando diferentes blocos de código conforme o resultado de expressões booleanas.

O PHP avalia expressões em contextos booleanos de forma flexível. Além dos valores true e false, existem valores considerados truthy (que se comportam como verdadeiros) e falsy (que se comportam como falsos). São considerados falsy: 0, 0.0, "", "0", null, array() (array vazio) e objetos que implementam __toString() retornando string vazia. Todo o resto é truthy.

A indentação consistente (geralmente 4 espaços) é fundamental para legibilidade, especialmente em condicionais aninhadas.

<?php
// Exemplo de truthy/falsy
$nome = "";
if ($nome) {
    echo "Nome preenchido"; // Não executa, pois string vazia é falsy
} else {
    echo "Nome vazio"; // Executa
}
?>

2. If, Else e Elseif

A estrutura if é a base das condicionais. Ela executa um bloco de código se uma condição for verdadeira.

<?php
$idade = 18;
if ($idade >= 18) {
    echo "Maior de idade";
}
?>

O else fornece uma alternativa quando a condição do if é falsa:

<?php
$idade = 16;
if ($idade >= 18) {
    echo "Pode dirigir";
} else {
    echo "Não pode dirigir";
}
?>

O elseif permite encadear múltiplas condições de forma elegante:

<?php
$nota = 85;
if ($nota >= 90) {
    $conceito = "A";
} elseif ($nota >= 80) {
    $conceito = "B";
} elseif ($nota >= 70) {
    $conceito = "C";
} else {
    $conceito = "D";
}
echo "Conceito: $conceito"; // B
?>

Em validação de formulários, o uso de if/else é comum para verificar campos obrigatórios:

<?php
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$senha = $_POST['senha'] ?? '';

if (!$email) {
    echo "Email inválido";
} elseif (strlen($senha) < 8) {
    echo "Senha deve ter no mínimo 8 caracteres";
} else {
    echo "Cadastro válido!";
}
?>

3. Aninhamento e Operador Ternário

Condicionais aninhadas são úteis, mas devem ser usadas com moderação para não prejudicar a legibilidade:

<?php
$usuario = ['admin' => true, 'ativo' => true];

if ($usuario['admin']) {
    if ($usuario['ativo']) {
        echo "Acesso total ao painel";
    } else {
        echo "Usuário inativo";
    }
} else {
    echo "Acesso negado";
}
?>

O operador ternário (? :) é um atalho para if/else simples:

<?php
$idade = 20;
$status = ($idade >= 18) ? "Adulto" : "Menor";
echo $status; // Adulto
?>

Cuidado com ternários encadeados, que podem prejudicar a legibilidade:

<?php
// Evite isso:
$tipo = ($a > $b) ? (($a > $c) ? "A maior" : "C maior") : "B maior";

// Prefira isso:
if ($a > $b && $a > $c) {
    $tipo = "A maior";
} elseif ($b > $c) {
    $tipo = "B maior";
} else {
    $tipo = "C maior";
}
?>

O Elvis operator (?:) retorna o operando esquerdo se ele for truthy, senão o direito:

<?php
$nome = $_GET['nome'] ?: "Visitante";
?>

O Null coalescing operator (??) verifica especificamente se o valor é null:

<?php
$nome = $_GET['nome'] ?? "Visitante";
?>

4. Switch: Controle por Múltiplos Valores

O switch é ideal quando você precisa comparar uma única variável contra múltiplos valores possíveis:

<?php
$dia = "segunda";

switch ($dia) {
    case "segunda":
        echo "Início da semana";
        break;
    case "sexta":
        echo "Sextou!";
        break;
    case "sabado":
    case "domingo":
        echo "Fim de semana";
        break;
    default:
        echo "Dia comum";
}
?>

Importante: o switch usa comparação com == (type juggling), o que pode causar resultados inesperados:

<?php
$valor = "2";
switch ($valor) {
    case 2:
        echo "Inteiro 2"; // Executa devido ao type juggling
        break;
    case "2":
        echo "String 2";
        break;
}
?>

O fall-through (ausência de break) pode ser intencional, como no exemplo de sábado/domingo, mas requer cuidado:

<?php
$opcao = 2;
switch ($opcao) {
    case 1:
        echo "Opção 1";
        // Sem break - continua para case 2
    case 2:
        echo "Opção 2"; // Executa para opção 1 e 2
        break;
}
?>

Em loops, continue pode substituir break para pular iterações:

<?php
for ($i = 1; $i <= 5; $i++) {
    switch ($i) {
        case 3:
            continue 2; // Pula para próxima iteração do for
        default:
            echo "$i ";
    }
}
// Resultado: 1 2 4 5
?>

5. Match: A Evolução do Switch (PHP 8.0+)

O match é uma expressão (não estrutura de controle) que retorna um valor e usa comparação estrita (===):

<?php
$statusCode = 404;

$mensagem = match ($statusCode) {
    200 => "OK",
    301, 302 => "Redirecionamento",
    404 => "Não encontrado",
    500 => "Erro interno",
    default => "Código desconhecido"
};

echo $mensagem; // Não encontrado
?>

Principais diferenças do match para o switch:

  1. Comparação estrita (===) - sem type juggling
  2. É uma expressão - retorna valor diretamente
  3. Sem fall-through - cada braço é independente
  4. Múltiplas condições separadas por vírgula
  5. Exige exaustividade - sem default, lança erro se nenhum braço corresponder

Exemplo prático de mapeamento de status:

<?php
function obterStatusPedido(string $status): string {
    return match ($status) {
        'pendente' => 'Aguardando pagamento',
        'pago' => 'Processando',
        'enviado' => 'Em trânsito',
        'entregue' => 'Concluído',
        default => 'Status inválido'
    };
}

echo obterStatusPedido('pago'); // Processando
?>

6. Comparações Avançadas e Boas Práticas

O match pode trabalhar com expressões mais complexas, incluindo arrays e funções anônimas:

<?php
$valor = 10;
$resultado = match (true) {
    $valor < 0 => 'Negativo',
    $valor === 0 => 'Zero',
    $valor > 0 && $valor <= 10 => 'Pequeno',
    $valor > 10 => 'Grande'
};
echo $resultado; // Pequeno
?>

Early return é uma técnica que simplifica condicionais complexas:

<?php
function validarUsuario(array $dados): string {
    if (empty($dados['email'])) {
        return 'Email obrigatório';
    }

    if (!filter_var($dados['email'], FILTER_VALIDATE_EMAIL)) {
        return 'Email inválido';
    }

    if (strlen($dados['senha'] ?? '') < 8) {
        return 'Senha muito curta';
    }

    return 'Usuário válido';
}
?>

Quando preferir cada estrutura:

  • if/elseif: Para condições complexas, intervalos numéricos, múltiplas variáveis envolvidas
  • switch: Para comparação de uma variável com múltiplos valores (PHP < 8.0) ou quando fall-through é necessário
  • match: Para comparação estrita com retorno de valor (PHP 8.0+), especialmente em mapeamentos

Performance e legibilidade: O match geralmente oferece melhor performance que switch em PHP 8.0+ devido à comparação estrita e ausência de fall-through. Contudo, a diferença é mínima para a maioria dos casos. Priorize sempre a legibilidade do código.

<?php
// Exemplo completo: processamento de requisição HTTP
function processarRequisicao(string $metodo): array {
    return match ($metodo) {
        'GET' => ['status' => 200, 'dados' => $_GET],
        'POST' => ['status' => 201, 'dados' => $_POST],
        'PUT', 'PATCH' => ['status' => 200, 'dados' => file_get_contents('php://input')],
        'DELETE' => ['status' => 204, 'dados' => null],
        default => ['status' => 405, 'dados' => 'Método não permitido']
    };
}

$resposta = processarRequisicao('POST');
echo "Status: {$resposta['status']}";
?>

Referências