# PHP para Iniciantes: Estruturas de Controle - INCLUDE, REQUIRE, INCLUDE_ONCE e REQUIRE_ONCE

Ok, eu falei que o artigo de hoje seria sobre `require`, mas não que seria somente isso, hehe. Eu decidi de última hora falar de todas as variações de inclusão de arquivo pois suas operações são bem semelhantes, pra não dizer praticamente iguais. A ação do código é exatamente a mesma, as diferenças estão na semântica. Então por que não começarmos refletindo sobre isso, como de costume?

## Reflexão sobre semântica

**Include** significa **incluir** em inglês e sua ação é sempre voltada a outro arquivo. Com isso podemos entender que sua proposta semântica é `INCLUA (arquivo)`, simples assim.

Já **require**, significa **necessitar**, o que remete ao cenário de que seu script **precisa** de outro arquivo para funcionar corretamente. Nesse caso, já podemos ver um certo acúmulo de responsabilidades... Pois **necessitar** e **incluir** são verbos distintos, mas no PHP, ambos são executados no `require`.

> Kiko, eu ainda não concordo com o acúmulo... Não ficou muito claro.

É simples. Quando você escreve `require "arquivo.php"`, o que você lê, semanticamente falando? `REQUER "arquivo.php"`. Beleza, você falar ao interpretador que `REQUER (algo)`, dá a entender que basta verificar se esse arquivo já foi incluído alguma vez, não? Porém, o que o `require` faz é acionar o `include` e, se o arquivo não existir, dispara um erro de compilação (** E_COMPILE_ERROR**), encerrando a interpretação do código.

Ou seja, a semântica literal acaba sendo `INCLUA OBRIGATORIAMENTE (arquivo)`. O nome poderia ser algo do tipo `include_required()`, entende? Por isso eu penso que o nome por si só não foi a melhor das melhores escolhas... E tudo bem! O que importa é que você vai lembrar pra que serve o `require`. Além disso, essa chamada existe em outras linguagens dessa mesma forma, portanto, não é tão estranha assim no mundo da programação.

## Na prática

Ao contrário do que costumarmos pensar, o arquivo incluído com `include` ou `require` **não precisa ser um script PHP**. Porém, como nosso interpretador só consegue entender PHP, se você colocar qualquer outro tipo de arquivo, ele só vai pegar seu conteúdo e jogar no buffer de saída da requisição.

> Tá, mas por que alguém iria incluir outra coisa, Kiko?

Ora, para fazer tratamentos ou atalhos! Eu mesmo já fiz um script para capturar dinamicamente imagens de um bucket S3 da Amazon, salvar na cache da aplicação e abrir ali mesmo. Então os usuários, ao invés de abrir diretamente a imagem no servidor de hospedagem, acessavam uma cache temporária criada na aplicação via script PHP. Mas **eu não fiz isso com `include`, e sim com a função `file_get_contents()`**.

> Ué, por quê, Kiko?

Pois tem muita diferença na semântica e nas consequências. As estruturas `include` e `require` fazem com que o interpretador **tente interpretar** o arquivo incluído. Isso significa que, se por algum motivo, existir alguma tag de abertura de interpretação (`<?php` ou `<?`), o PHP vai tentar interpretar e provavelmente não vai ser nada legal.

Por isso, se você está tentando incluir os dados de um arquivo onde você notoriamente sabe que seu conteúdo **não é nada em PHP**, há funções mais seguras e que podem até melhorar a semântica no seu fluxo.

`$bin = file_get_contents('image.png');` é bem mais claro, não é?

Ainda assim, funciona para outros arquivos sim. Ah, e também funciona para links!

> Quê?!

Sim, é possível incluir scripts externos à sua aplicação, mas, nesse caso, as estruturas só funcionam para scripts PHP. Qualquer outro formato resultará em erro.

## Configurações

Sobre tudo isso que mencionei acima, tem alguns pontos importantes de mencionar sobre a configuração do PHP. Para que cada caso funcione, você precisa se ligar nessas duas palavrinhas:

- `include_path`: se você não quiser ficar escrevendo o diretório e todos os arquivos que você quer incluir ficam na mesma pasta, você pode inserir o caminho absoluto dessa pasta nessa configuração. Assim, se você definir `include_path=/var/inc/`, quando você fizer `include('arquivo.php')`, o interpretador tentará incluir o arquivo `/var/inc/arquivo.php`. Se essa configuração não for preenchida, a inclusão de arquivos sem diretórios será feita a partir da pasta do escopo do script. Nesse caso, se o arquivo está em `/var/www`, aquele `include` tentaria incluir o arquivo `/var/www/arquivo.php`. Não existe um `require_path`, porque esse aqui também afeta o `require`. Se você quiser usar o caminho relativo quando tiver preenchido essa configuração, basta colocar a notação de diretório relativo `'./'`, ficando `include('./arquivo.php')`. Também é possível usar a notação de "diretório-pai" `'../'`;
-  `allow_url_include`: se você deseja incluir links, essa configuração precisa ser `true`. **Não é recomendado**, então nem conte com isso. Se ainda assim quiser ativar, verifique os [protocolos suportados pelo PHP listados na documentação oficial](https://www.php.net/manual/pt_BR/wrappers.php).

## Retorno

Assim como mencionado no artigo anterior, se o script incluído encerrar sua chamada com a estrutura `return`, o retorno da inclusão será o que for passado aqui. Porém, se nada for retornado, então teremos duas situações na estrutura `include`:

- `1`, se conseguiu incluir;
- `false`, se não, emitindo um erro de alerta (**E_WARNING**).

No caso do `require`, se não conseguir incluir, o interpretador emitirá o erro de compilação que mencionei mais cedo, então nem faz sentido ele ter algum retorno condicionado, não é?

## Sintaxe

Ok, falei, falei, falei... E não mostrei nada. Bem, só tem duas sintaxes possíveis:

### 1 - Como uma função (com parênteses)
- `include('arquivo')`
- `require('arquivo')`

### 2 - Como um operador, sem parênteses

- `include 'arquivo'`
- `require 'arquivo'`

Nenhuma das duas formas é abominada no mercado. O importante aqui é você sempre manter o padrão do projeto: se usa um, continue usando dessa forma!

## Exemplos

Agora vamos trabalhar em cases!

Vamos supor que você está montando um formulário e que, no final do processo, você deseja incluir a assinatura do chefe. Essa assinatura está estruturada no arquivo `includes/assinatura.php` e você não precisa mexer nela, sendo o HTML retornado pelo script via estrutura `return` ao invés de ser impresso no buffer. Como fica esse arquivo?

```php
<?php
$html = '<!DOCTYPE html><html><head></head><body>';
// ... código mágico aqui, onde geramos o HTML
$html .= include('./includes/assinatura.php');
$html .= '</body></html>';
// pronto, html concluído.
```

> Ah, Kiko, e se o arquivo fosse `includes/assinatura.html`?

Nesse caso, o ideal não seria usar o `include`, mas ainda seria possível com as funções de manipulação de buffer `ob_start()` e `ob_get_clean()`:

```php
<?php
$html = '<!DOCTYPE html><html><head></head><body>';
// ... código mágico aqui, onde geramos o HTML
ob_start(); // inicia a captura de buffer da requisição
include('./includes/assinatura.html'); // joga todo o HTML no buffer
$html .= ob_get_clean(); // seta o que capturou em $html e remove do buffer
$html .= '</body></html>';
// pronto, html concluído.
```

> E se houver a chance do HTML não existir, Kiko?

Aí é onde podemos aplicar o `require`:

```php
<?php
$html = '<!DOCTYPE html><html><head></head><body>';
// ... código mágico aqui, onde geramos o HTML
ob_start(); // inicia a captura de buffer da requisição
require('./includes/assinatura.html'); // joga todo o HTML no buffer
$html .= ob_get_clean(); // seta o que capturou em $html e remove do buffer
$html .= '</body></html>';
// pronto, html concluído.
```

## Inclusões únicas

Além das estruturas `include` e `require`, também é possível encontrar as variantes `_once` (`include_once` e `require_once`). O papel aqui é atribuir mais um dever à estrutura: o de verificar se é a primeira vez que o arquivo ou link está sendo incluído pelo interpretador.

Isso serve para evitar recursões infinitas ou evitar que um código seja incluído mais de uma vez na mesma requisição (o que caracteriza certa falta de controle sobre o código).

Por exemplo, em códigos mais antigos, é comum encontrar um arquivo exclusivo de conexão ao banco de dados. Quando você encontra projetos assim, você já pode imaginar que a variável de conexão representa uma variável global. Porém, a pessoa que escreve esse tipo de código não quer correr o risco de ficar reescrevendo a conexão toda hora... O que ela faz?

Bom, em todo fluxo que precisa ter conexão com o código, ela chama a estrutura `include_once`. Se o script nunca foi incluído, então será interpretado e inicializará a conexão pela primeira vez. Mas se já foi, então a instrução será ignorada.

Funciona da mesma forma no `require_once`: ah, o banco é obrigatório, se o arquivo não existir então precisamos parar a execução daquele código. Então ao invés de `include_once`, o `require_once` será escolhido.

Nota: apesar de eu não aprovar códigos escritos assim, eu não estou repudiando essas ações! Códigos escritos dessa forma são evidências de que o desenvolvedor está tentando organizar alguma coisa, no final das contas, e evitando repetição de código. Então está menos mal. Não se sinta ruim se já fez códigos assim, beleza? Mas vamos melhorar, por favor!

E por hoje é só! Curtiu? Comenta e compartilha! Você já conhecia o `include` e `require`? Fala aí pra eu ver uma coisa, rs. No próximo artigo, falarei sobre a última estrutura de controle: **GOTO**. Quem já mexeu com linguagem antiga já vai sacar... Mas não deixe de ler, hein?

**Inté!!**
