PHP para Iniciantes: Estruturas de Controle - Else / Elseif / Else if

No artigo anterior, falamos sobre a primeira estrutura de controle, o if, que nos dá a possibilidade de determinar condições para executar determinadas instruções. As estruturas que vamos conhecer agora são uma extensão dessa estrutura: não existem sem o if.

1 - else

A frase que usamos para refletir sobre o if é SE {isso} ENTÃO {aquilo}, certo? Bem, para encaixar um else nesse contexto, aumentaríamos a frase para SE {isso} ENTÃO {aquilo1}, SE NÃO {aquilo2};. É simplesmente isso: se não entra no if, entra no else.

<?php

if (true) {
    // aqui entra
} else {
    // ignora totalmente, já que entrou no if
}

if (false) {
    // aqui não entra
} else {
    // entra, pois não entrou no if
}

Assim, você pode criar uma alternativa para quando a condição não é cumprida... Isso te lembra alguma coisa?... Pois é, eu fiz um exemplo com if-else no artigo sobre Operadores de Anulidade e é basicamente isso. Obviamente, essa não é a única forma de se utilizar um else, pois ao combinar com a estrutura abaixo, ele recebe outro significado.

2 - elseif / else if

Esse parece até complexo de traduzir em uma frase semântica: SE {isso1} ENTÃO {aquilo1}, OU SE {isso2} ENTÃO {aquilo2}, OU SE (...);. Você pode criar uma série de "blocos condicionados" onde o interpretador só irá entrar em um, que seria o primeiro cujas condições fossem cumpridas. Por exemplo:

<?php

if (false) {
    // não entra, pois é false
} elseif (false) {
    // não entra
} elseif (true) {
    // entra, pois é true
} elseif (true) {
    // mesmo sendo true, não entra, pois entrou no bloco anterior
}

E qual a diferença entre elseif e else if, Kiko?

Na prática? Nenhuma. Você lembra que no artigo passado eu mencionei uma forma de escrever um if sem bloco de código?

<?php

if (true)
    echo 'Alguma coisa';

No else if é a mesma coisa, só que a instrução que é passada é o if!

<?php

// isso
if (false) {
    // ...
} else if (true) {
    // ...
}

// equivale a isso
if (false) {
    // ...
} else {
    if (true) {
        // ...
    }
}

Kiko, você mencionou um significado diferente para o else combinado com o elseif. Que significado é esse?

Opa, sim! Até então temos ciência de três cenários:

  • if: SE {isso} ENTÃO {aquilo};
  • if-else: SE {isso} ENTÃO {aquilo1}, SE NÃO {aquilo2};
  • if-elseif: SE {isso1} ENTÃO {aquilo1}, OU SE {isso2} ENTÃO {aquilo2}.

Se encaixarmos um else no último exemplo, o que temos é:

if-elseif-else => SE {isso1} ENTÃO {aquilo1}, OU SE {isso2} ENTÃO {aquilo2}. SE NENHUMA CONDIÇÃO FOR CUMPRIDA, ENTÃO {aquilo3}

Meio gigante, né? Mas se fôssemos traduzir semanticamente (usando português simples) seria dessa forma mesmo.

Sintaxe procedural

Além da minúscula diferença que mencionei entre elseif vs. else if, tem outro fato que é importante mencionar... Não existe else if (separado) na escrita procedural, somente a escrita unificada. Os demais, funcionam da mesma forma que mencionei no artigo anterior:

<?php

if (false):
    // ...
elseif (true):
    // ...
else:
    // ...
endif;

3 - Conclusão e dicas

Tudo o que apresentei nesse artigo é legal, certo? E a utilidade é muito boa - mas não tão necessárias assim.

Ué, Kiko... Se não são tão necessárias, por que existem?

Porque o PHP é uma linguagagem que te dá liberdade para fazer o que quiser

Stonks

E quando eu digo que as estruturas de hoje podem ser desnecessárias, varia de situação pra situação. O melhor exemplo que gosto de mencionar é o Early Return, que pode ser traduzido como Retorno Precoce, sendo aplicado em métodos e/ou funções, retirando a necessidade de um else no final. Também gosto de mencionar o Object Calisthenics, especificamente sobre uma regra que nos orienta a não escrever nenhuma palavra-chave com else, somente if. Tem mais a ver com qualidade de código em si.

Early Return

Em algum momento na vida, você vai se deparar com uma situação onde você vai escrever um método ou função que se comporta da seguinte forma:

<?php

function exemplo(int $entrada): int
{
    $resultado = 0;
    if ($entrada === 1) {
        $resultado = 2;
    } elseif ($entrada === 2) {
        $resultado = 5;
    } else {
        $resultado = 9;
    }
    return $resultado;
}

Basicamente, dado um argumento de entrada $entrada, você gera um resultado condicionado. Há muitas formas de escrever esse código... Com switch teríamos um outro exemplo interessante... Com match seria um exemplo maravilhoso... Mas essas são estruturas que ainda não mencionei, então deixei tudo na base do if mesmo.

Ok, Kiko... Mas qual problema temos aqui? Não está funcionando?

Está, mas é realmente necessário percorrer até a última linha da função para executar? E se numa manutenção, você acrescentar algo depois do else e gerar um acúmulo de responsabilidades? Bem, Early Return é a forma ideal de contornar esses riscos:

<?php

function exemplo(int $entrada): int
{
    if ($entrada === 1) {
        return 2;
    } elseif ($entrada === 2) {
        return 5;
    }
    return 9;
}

Percebe que, ao invés de colocar o resultado em uma variável, eu já retornei a informação? É isso que é early return.

Mas Kiko, e o else?

Removi dicumforça (tradução: na base da porrada).

E o motivo é simples: se o código não entrou em nenhuma condicional, ao sair da estrutura de if, o resto do código é o else!

Mind Blown - GIPHY

O código fica bem mais enxuto, você pode ver com clareza as possibilidades de retorno e se alguém fizer algum bug depois da primeira linha, provavelmente não vai matar o método todo, rs.

Object Calisthenics

O que é isso, Kiko?!

É um conjunto de boas práticas de desenvolvimento, introduzido pelo mestre Jeff Bay no livro Thought Works Anthology. Com essa descrição, você já deve imaginar que tem um monte de regras interessantes e eu, com certeza, não vou falar tanto sobre isso. Quero mencionar somente uma das nove regras: não use a palavra-chave ELSE.

Em conjunto com o Early Return, essa regra do Object Calisthenics faz todo o sentido:

<?php

function exemplo(int $entrada): int
{
    if ($entrada === 1) {
        return 2;
    }
    // o elseif virou um if isolado
    if ($entrada === 2) {
        return 5;
    }
    return 9;
}

Nessa situação, é bem claro enxergar essa possibilidade, pois o primeiro if já tem um return. Mas essas coisas também são possíveis sem Early Return, você só precisa analisar com cuidado se as regras não se sobrepõem (por exemplo, se há alguma chance de entrar em mais de uma condição, você realmente vai precisar manter o elseif).

E para encerrar, deixo aqui a sugestão de leitura: Object Calisthenics. Não coloquei nenhum link para esse estudo pois tem muito assunto incrível por aí, inclusive gratuito, e gostaria de te deixar um dever de casa: aprenda a pesquisar!

HEHEHE

Enfim, curtiu?! Comenta e compartilha! No próximo artigo, falaremos sobre a estrutura de controle while, que controla repetições condicionadas de um bloco de código. Fechou?!

Inté!!