# PHP para Iniciantes: Estruturas de Controle - GOTO

A imagem a seguir é a introdução atual do [artigo na documentação oficial do PHP](https://www.php.net/manual/pt_BR/control-structures.goto.php), uma cortesia do [xkcd](http://xkcd.com/292).

![GOTO](https://www.php.net/manual/pt_BR/images/0baa1b9fae6aec55bbb73037f3016001-xkcd-goto.png)

Traduções para quem não manja do inglês:

- Q. 1: Eu poderia reestruturar o fluxo do programa - ou usar um pequeno 'GOTO' ao invés disso.
- Q.2 : Ah, dane-se as boas práticas. Quão errado pode ser isso? `goto main_sub3;` ... \*compila\*

E aí acontece a invocação do dinossauro de dentro deste ser.

Bem, isso por conta própria já reflete a opinião (quase) unânime sobre o uso dessa estrutura de controle. Se você planeja aprender para usar, é melhor nem ler o resto do artigo, rs.

> Ué, Kiko, por que você está escrevendo então?

Assim como eu precisei escrever sobre o operador de controle de erro (`@`), eu também preciso escrever sobre `goto`. É aquele tipo de coisa que você precisa aprender para evitar utilizar e saber como desfazer caso encontre um projeto usando, sabe?

Enfim, apesar de todo esse terror psicológico, `goto` na verdade é uma das estruturas mais simples que existe, porque ele ordena exatamente o que propõe: `VÁ PARA (referênciaDoLugar)`. O que pode ser não tão claro assim é sobre como construir uma referência, de fato.

*É um nome? Uma linha? Um arquivo? A casa do **Car**-los?*

Essa referência é um **nome** que funciona como um ponteiro, você precisará criar uma identificação para uma seção e esse nome vai funcionar como a porta de entrada para a chamada do `goto`.

**O nome não precisa existir na interpretação antes da chamada dessa estrutura**, mas **precisa estar no mesmo escopo**. Sendo assim, você não pode fazer um salto entre funções, nem de dentro para fora nem de fora para dentro, pois são escopos diferentes.

Apesar de você não conseguir saltar para dentro de um laço de repetição (*loop*) ou de um `switch`, você consegue acionar o `goto` de dentro dessas estruturas, funcionando como um `break`, pois o escopo de fora delas ainda é o mesmo escopo. Mesmo assim, você só pode saltar para áreas identificadas no mesmo escopo, não fora.

> Ah, Kiko, mostra como raios funciona isso logo...

Ok!

## Exemplo 1: casa do Carlos

```php
<?php

goto casaDoCarlos;
echo 'Eu não sou cachorro não' . PHP_EOL;



casaDoCarlos:
echo 'De bar em bar, de mesa em mesa...';
```

O resultado disso será

```html
De bar em bar, de mesa em mesa...```

E o que ocorre é bem simples: o interpretador vê o comando `goto`, verifica se já interpretou alguma identificação para saltar, o que não ocorreu, então passa a buscar uma instrução que indique o nome `casaDoCarlos`. Ao encontrar, salta para aquele ponto e volta a interpretar.

O que significa, que se fosse ao contrário, também funcionaria... Mas é preciso tomar cuidado com **loops infinitos**. Para o exemplo abaixo, vou colocar um contador que ao ser contado duas vezes, irá encerrar o código para evitar isso.

## Exemplo 2: de volta para o futuro

```php
<?php

$ano = 2021;
$contador = 0; // antes do loop né?
futuro:
echo "Estamos em $ano!" . PHP_EOL;

if(++$contador < 2) {
    $ano = 2077;
    goto futuro;
}
echo 'O_O';
```

E o resultado desse é:

```html
Estamos em 2021!
Estamos em 2077!
O_O
```

Ou seja, é possível demarcar uma zona de retorno para saltar com o `goto`. Sim, é possível fazer loops com `goto`. Também é possível encerrar os loops com ele...

## Exemplo 3: o falso `break`

```php
<?php // PHP 8

$valido = fn() => false; // imagine que isso aqui é uma função que retorna true/false

for ($algumaCoisa = 0; $algumaCoisa < 1000; $algumaCoisa++) {
    if (!$valido()) {
        goto end; // break?
    }
    echo $algumaCoisa . PHP_EOL;
}

end:
echo 'É o fim, e ele nem tinha começado...';
```

Resulta em:

```html
É o fim, e ele nem tinha começado...
```

## Detalhes...

Tem uma *parada* que preciso mencionar: esses nomes não podem ser expressões nem tipos de dados primitivos. Colocar uma `string` não funciona, tampouco uma variável. Se escrever uma constante, ele vai pegar a escrita, não o valor da constante:

```php
<?php

define('END', 'É O FIMMMMMMMM');

goto END;

END: // o goto vai saltar para cá, naturalmente, o ponto END
echo END; // e aqui vai usar o valor da constante
```

> Kiko, parece bem prático...

**NÃO, NÃO É PRÁTICO**. Isso é uma **ILUSÃO**. Você até pode resolver uma urgência com isso mas certamente precisará refatorar o código depois, pois fica bizarro, beleza? Você pode pesquisar por exemplos na web e se você acompanha as boas práticas de desenvolvimento, você vai entender porque, apesar de parecer legal e prático, não é.

E por hoje é só! Curtiu?! Comenta e compartilha!! Esse foi o último artigo sobre estruturas de controle, o que indica que tem mais uma introdução vindo por aí... A partir do próximo, falaremos sobre **FUNÇÕES** (aaaaaleluia, aaaaaaaleluia). Como de costume, vou dar uma visão geral sobre o assunto com micro *spoilers* pra você pegar a ideia básica e só depois vou me aprofundar em cada trecho dessa seção maravilhosa, beleza??!

**Inté!!**
