# Espaços de nomes e autoloading (PSR-4)

> Espaços de nomes e autoloading em PHP com PSR-4: do nome da classe ao caminho do ficheiro, spl_autoload_register, autoloader do Composer e verificação após incidentes.

Fonte: https://phpsos.de/pt/php/namespaces-autoloading/  
Atualizado em: 25/10/2026  
Prestador: PHP SOS, Assistência de emergência PHP e segurança de servidores. Ajuda imediata por WhatsApp: https://wa.me/491736494914?text=Ol%C3%A1%2C%20PHP%20SOS%2C%20precisamos%20de%20ajuda%20com%20o%20nosso%20servidor%20PHP.%20Empresa%3A%20%E2%80%A6%20Site%3A%20%E2%80%A6

**Em resumo:** Os espaços de nomes são, em PHP, algo como pastas para nomes de classes: `App\Rechnung\Pdf` e `Bibliothek\Pdf` podem coexistir sem se perturbarem. O autoloading faz com que o PHP só carregue uma classe quando ela é usada pela primeira vez. O padrão PSR-4 define como um nome de classe passa a caminho de ficheiro; o Composer gera depois o autoloader adequado. Como este autoloader corre em cada pedido, é uma das primeiras coisas a verificar após um incidente de segurança.

## Porque é que o PHP precisa de espaços de nomes

Os espaços de nomes existem desde o PHP 5.3.0. Antes, todas as classes e funções partilhavam um único espaço de nomes global. Se duas bibliotecas se chamassem `Logger`, havia um colapso. Os programadores arranjavam-se com nomes longos como `Firma_Modul_Unterbereich_Logger`.

O manual do PHP indica dois problemas que os espaços de nomes resolvem: colisões de nomes entre código próprio, classes internas do PHP e bibliotecas de terceiros, e nomes demasiado longos que surgiram apenas para contornar essas colisões. Para quem decide, isto significa: só com os espaços de nomes se tornou praticável combinar dezenas de pacotes alheios num projeto, como hoje é habitual com o [Composer](https://phpsos.de/pt/php/composer/).

## Espaços de nomes na prática: namespace, use, aliases

Um ficheiro declara o seu espaço de nomes na primeira instrução. Com `use` trazem-se classes de outros espaços de nomes, se desejado com um nome mais curto.

```php
<?php
declare(strict_types=1);

namespace App\Rechnung;

use App\Kunde\Kunde;
use Psr\Log\LoggerInterface as Log;

final class PdfErzeuger
{
    public function __construct(private Log $log) {}

    public function erzeugen(Kunde $kunde): string
    {
        $this->log->info('PDF erzeugt', ['kunde' => $kunde->id]);
        return \sprintf('Rechnung für %s', $kunde->name);
    }
}
```

O nome completo desta classe é `App\Rechnung\PdfErzeuger`. A barra invertida inicial em `\sprintf` remete expressamente para a função global do PHP.

## Autoloading: carregar classes quando necessário

Sem autoloading, cada script teria de incluir com `require` todos os ficheiros de que precisa. Com `spl_autoload_register()` regista-se, em vez disso, uma função que o PHP chama assim que é usada uma classe, interface, trait ou enum desconhecidos. Recebe o nome da classe e carrega o ficheiro correspondente.

```php
<?php
spl_autoload_register(function (string $klasse): void {
    $praefix = 'App\\';
    $basis   = __DIR__ . '/src/';

    if (!str_starts_with($klasse, $praefix)) {
        return; // não é da sua competência, a vez é do autoloader seguinte
    }
    $datei = $basis . str_replace('\\', '/', substr($klasse, strlen($praefix))) . '.php';
    if (is_file($datei)) {
        require $datei;
    }
});
```

O `spl_autoload_register()` pode ser chamado várias vezes. O PHP consulta então os autoloaders registados um a seguir ao outro, até que um tenha carregado a classe. Na prática, as aplicações grandes têm muitas vezes vários: o autoloader do Composer para as bibliotecas, um próprio do CMS e outros de plugins ou módulos. Para os administradores, isto significa: o código que é realmente carregado num pedido resulta da interação de todos estes autoloaders e não apenas da estrutura de pastas.

O manual desaconselha vivamente lançar exceções num autoloader; o PSR-4 proíbe-o expressamente. A função mais antiga `__autoload()` foi marcada como obsoleta no PHP 7.2.0 e removida no PHP 8.0.0.

## PSR-4: do nome da classe ao caminho do ficheiro

O PSR-4 é um padrão da PHP-FIG. Um nome de classe completo começa com um espaço de nomes do fabricante. Um prefixo do espaço de nomes é associado a um diretório base, o resto do nome dá as subpastas e o ficheiro termina em `.php`. A distinção entre maiúsculas e minúsculas tem de coincidir exatamente. Assim se vê a associação no `composer.json`:

```json
{
    "autoload": {
        "psr-4": { "App\\": "src/" }
    }
}
```

| Nome da classe | Ficheiro |
|---|---|
| `App\Kunde\Kunde` | `src/Kunde/Kunde.php` |
| `App\Rechnung\PdfErzeuger` | `src/Rechnung/PdfErzeuger.php` |
| `App\Rechnung\Pdf\Vorlage` | `src/Rechnung/Pdf/Vorlage.php` |

Um obstáculo clássico é a distinção entre maiúsculas e minúsculas. Em computadores de desenvolvimento com Windows ou macOS, o sistema de ficheiros muitas vezes não distingue entre `Kunde.php` e `kunde.php`, mas num servidor Linux distingue. Uma aplicação que corre localmente não encontra então uma classe no servidor. A regra do PSR-4 de usar os nomes exatamente na grafia correta evita estas surpresas na entrega.

Além de `psr-4`, o Composer conhece `classmap`, para código sem estrutura padrão, e `files`, para ficheiros carregados em todos os pedidos, por exemplo funções auxiliares. Outros padrões da PHP-FIG são descritos na página [Padrões PSR](https://phpsos.de/pt/php/psr-standards/).

## Otimizar o autoloader em produção

Em produção, o ideal é que o autoloader já não procure no sistema de ficheiros, mas consulte uma lista pronta. O Composer oferece para isso dois níveis:

1. `composer install --no-dev --optimize-autoloader` converte as regras PSR-4 numa lista de classes. Segundo a documentação do Composer, é recomendado para produção.
2. `--classmap-authoritative` vai mais longe: as classes são carregadas exclusivamente a partir da lista. Os ficheiros que nela não constem, o autoloader nem sequer os carrega.
3. A cada entrega, a lista é gerada de novo, para que as classes novas sejam encontradas.

## Autoloading e segurança após o PHP2Shell

O PHP2Shell diz respeito ao interpretador PHP, não ao autoloader. Continuam obrigatórios a atualização para o PHP 8.5.12, 8.4.27, 8.3.36 ou 8.2.35 e o reinício de todos os workers. Após um possível incidente, o autoloader merece, porém, atenção especial: o `vendor/autoload.php` e todos os ficheiros registados em `files` são executados a cada pedido. Uma linha aí introduzida atua, portanto, em todo o site, sem que haja um ficheiro novo e chamativo na pasta de uploads.

Verifique por isso se o `vendor` e os ficheiros de autoload correspondem ao estado verificado do controlo de versões. São úteis os artigos [Encontrar ficheiros alterados recentemente](https://phpsos.de/pt/blog/geaenderte-dateien-finden/) e [Comparar os ficheiros do núcleo do CMS com o original](https://phpsos.de/pt/blog/cms-kerndateien-vergleichen/). Em caso de dúvida, um `vendor` gerado de novo a partir do ficheiro lock é mais seguro do que qualquer reparação isolada.

## Como ajuda concretamente a PHP SOS?

- Comparamos o `vendor`, o autoloader e os ficheiros de entrada com o estado verificado e assinalamos qualquer desvio.
- Restabelecemos o conjunto de pacotes a partir do ficheiro lock e configuramos um autoloader otimizado.
- Verificamos se apenas a pasta pública está na raiz web e se o código-fonte não é diretamente acessível por URL.
- Em caso de infeção, assumimos a limpeza no âmbito da [remoção de malware](https://phpsos.de/pt/leistungen/malware-entfernung/) e documentamos o resultado.


## Perguntas frequentes

**Desde quando existem espaços de nomes no PHP?**  
Desde o PHP 5.3.0. Segundo o manual, resolvem dois problemas: colisões de nomes entre código próprio, o PHP e bibliotecas de terceiros, e nomes de classe demasiado longos que só surgiram para evitar essas colisões.

**Qual é a diferença entre PSR-0 e PSR-4?**  
Ambos mapeiam nomes de classe para caminhos de ficheiro. No PSR-4, o prefixo do espaço de nomes não se repete no caminho do ficheiro, o que dá diretórios mais planos. O PSR-0 está classificado como obsoleto pela PHP-FIG; o PSR-4 é o padrão recomendado.

**O __autoload() ainda funciona?**  
Não. O __autoload() foi marcado como obsoleto no PHP 7.2.0 e removido no PHP 8.0.0. Hoje registam-se autoloaders com spl_autoload_register(), na prática quase sempre através do autoloader gerado pelo Composer.

**Preciso de gerar de novo o autoloader depois de criar uma classe nova?**  
Com regras exclusivamente PSR-4, não; segundo a documentação do Composer, essa é precisamente uma vantagem do PSR-4. Quem usa em produção uma lista de classes otimizada tem de a gerar de novo em cada entrega.

## Fontes

- [PHP-FIG: autoloader PSR-4](https://www.php-fig.org/psr/psr-4/)
- [Manual do PHP: espaços de nomes, visão geral](https://www.php.net/manual/de/language.namespaces.rationale.php)
- [Manual do PHP: autoloading](https://www.php.net/manual/de/language.oop5.autoload.php)
- [Composer: o esquema do composer.json](https://getcomposer.org/doc/04-schema.md)
