Aikido

Como corrigir erros de autoload do PHP: correspondendo nomes de classes a nomes de arquivos

Risco de Bug

Regra
Classe nome deve corresponder ao nome do ficheiro.
Muitas idiomas requerem classe nomes
para coincidam nomes de ficheiros exatamente, ou eles irão
falhar em sensíveis a maiúsculas e minúsculas sistemas de ficheiros (Linux).

Linguagens suportadas: PHP

Introdução

O autoloading PSR-4 do PHP exige que os nomes das classes correspondam exatamente aos nomes dos arquivos, incluindo o uso de maiúsculas e minúsculas. Uma classe chamada UserRepository deve estar em UserRepository.php, não userrepository.php. Isso funciona em sistemas de arquivos que não diferenciam maiúsculas de minúsculas como Windows e macOS, mas falha em servidores Linux, causando erros de "Class not found" em produção.

Por que isso importa

Falhas de produção: Nomes incompatíveis causam falhas de autoload em servidores Linux onde os sistemas de arquivos diferenciam maiúsculas de minúsculas. O código que funciona localmente quebra em produção, exigindo hotfixes de emergência e causando tempo de inatividade.

Conformidade com PSR-4: Frameworks PHP modernos dependem do autoloading PSR-4. Classes que não seguem as convenções de nomenclatura não podem ser carregadas automaticamente, quebrando a injeção de dependência, service containers e recursos do framework.

Exemplos de código

❌ Não-conforme:

<?php
// File: userrepository.php

namespace App\Repositories;

class UserRepository
{
    public function findById($id)
    {
        return User::find($id);
    }

    public function save(User $user)
    {
        return $user->save();
    }
}

Por que está errado: O nome da classe é UserRepository mas o nome do arquivo é userrepository.php (minúsculas). O autoloader PSR-4 procurará por UserRepository.php e falham em encontrá-lo em sistemas de arquivos Linux que diferenciam maiúsculas de minúsculas, causando erros fatais em produção.

✅ Compatível:

<?php
// File: UserRepository.php

namespace App\Repositories;

class UserRepository
{
    public function findById($id)
    {
        return User::find($id);
    }

    public function save(User $user)
    {
        return $user->save();
    }
}

Por que isso importa: O nome do arquivo UserRepository.php corresponde ao nome da classe UserRepository exatamente, incluindo o case. O autoloader PSR-4 pode localizar e carregar a classe de forma confiável em qualquer sistema de arquivos, eliminando falhas específicas do ambiente e garantindo um comportamento consistente entre desenvolvimento e produção.

Conclusão

Imponha a correspondência estrita de nome de arquivo para nome de classe desde o início do seu projeto. Configure seu IDE para nomear arquivos corretamente automaticamente ao criar classes. Use verificações automatizadas em pipelines de CI/CD para detectar incompatibilidades antes da implantação. Os cinco minutos gastos garantindo a nomenclatura adequada evitam horas de depuração de falhas de autoload em produção.

FAQs

Dúvidas?

Por que isso funciona no Windows/macOS mas falha no Linux?

Windows e macOS usam sistemas de arquivos que não diferenciam maiúsculas de minúsculas por padrão (NTFS, APFS, HFS+). Quando o autoloader do PHP solicita UserRepository.php, esses sistemas retornarão userrepository.php porque eles tratam os nomes de arquivos como não sensíveis a maiúsculas e minúsculas. Linux usa sistemas de arquivos que diferenciam maiúsculas de minúsculas (ext4, xfs) onde UserRepository.php e userrepository.php são arquivos completamente diferentes. O autoloader falha porque procura uma correspondência exata.

Como encontrar todas as incompatibilidades de classe/nome de arquivo na minha base de código?

Escreva um script que escaneie arquivos PHP, extraia nomes de classes usando reflection ou regex, e os compare com os nomes dos arquivos. Muitas ferramentas de análise estática detectam violações de PSR-4. Em CI/CD, execute a validação do autoloader do Composer com composer dump-autoload --optimize --strict-psr. Isso detecta incompatibilidades antes do deploy. Algumas IDEs como PhpStorm destacam violações de PSR-4 durante o desenvolvimento.

E quanto a traits, interfaces e classes abstratas?

A mesma regra se aplica. Uma interface chamada UserRepositoryInterface deve estar em UserRepositoryInterface.php. Um trait chamado Timestampable requer Timestampable.php. Classes abstratas seguem o mesmo padrão. O PSR-4 trata todas as estruturas tipo classe de forma idêntica. O nome do arquivo deve corresponder exatamente ao nome da classe/trait/interface, incluindo o uso de maiúsculas e minúsculas.

Posso usar sublinhados ou hífens em nomes de arquivo?

Não para conformidade com PSR-4. Nomes de classes PHP não podem conter hífens ou a maioria dos caracteres especiais. Sublinhados são tecnicamente permitidos em nomes de classes, mas desencorajados pelos padrões PSR. Mantenha o PascalCase para nomes de classes e nomes de arquivos: UserRepository, não User_Repository ou user-repository. A consistência com as convenções PSR-4 garante a compatibilidade com o framework.

E se eu tiver múltiplas classes em um único arquivo?

Não. O PSR-4 exige uma classe por arquivo com nomes correspondentes. Múltiplas classes em um único arquivo quebram o autoloading porque o autoloader espera uma relação 1:1 entre nomes de classes e caminhos de arquivo. Se você tem classes fortemente acopladas, considere se elas deveriam ser classes internas, arquivos separados ou refatoradas em uma única classe coesa. Uma classe por arquivo é um requisito fundamental do PSR-4.

Como lidar com código legado que viola esta regra?

Corrija todas as inconsistências antes de implantar em servidores Linux, pois arquivos inconsistentes causarão falhas imediatas de autoload em produção. Use ferramentas de refatoração da IDE que renomeiam tanto a classe quanto o arquivo simultaneamente. No macOS, renomeações que alteram apenas o caso podem exigir dois commits git: primeiro renomeie para um nome temporário (UserRepository_temp.php), faça o commit, e depois renomeie para o caso correto (UserRepository.php). Para grandes bases de código, corrija todas as violações em um PR dedicado, teste exaustivamente e depois implante. Atualize o autoloader do Composer (composer dump-autoload) após renomear os arquivos.

O namespace afeta o nome do arquivo?

Namespace afeta a estrutura de diretórios, não o nome do arquivo em si. Uma classe App\\Repositories\\UserRepository deve estar em app/Repositories/UserRepository.php (ou src/Repositories/UserRepository.php, dependendo da sua raiz PSR-4). O namespace mapeia para diretórios, e o nome da classe mapeia para o nome do arquivo. Ambos devem seguir as convenções PSR-4: segmentos de namespace mapeiam para diretórios com correspondência de maiúsculas e minúsculas, nome da classe mapeia para nome do arquivo com correspondência de maiúsculas e minúsculas.

Fique seguro agora

Proteja seu código, Cloud e runtime em um único sistema centralizado.
Encontre e corrija vulnerabilidades rapidamente de forma automática.

Não é necessário cartão de crédito | Resultados da varredura em 32 segundos.