Médio PHP
Autoload PSR-4 manual
Enunciado
Implemente um autoloader que siga o padrão PSR-4 para o prefixo App\ mapeado para o diretório src/. Crie as classes App\Models\User (com getName()) e App\Services\UserService (com greet(User $user) retornando "Olá, " . $user->getName()). O autoloader deve carregar automaticamente os arquivos quando as classes forem usadas. No arquivo principal, registre o autoloader, instancie as classes e exiba a saudação.
Requisitos
- O autoloader verifica se o prefixo
App\corresponde ao início do nome da classe. - Converte o namespace para caminho de arquivo:
src/Models/User.php. - Inclui o arquivo apenas se ele existir.
- O programa principal usa as classes sem
requiremanual.
Código inicial
<?php
// Implemente o autoloader PSR-4 e as classes
Saída esperada
Olá, Maria
Ver dica
Use spl_autoload_register, str_replace para trocar \ por / e file_exists antes de incluir.
Mostrar solução
<?php
// autoload.php
spl_autoload_register(function ($class) {
$prefix = 'App\\';
$baseDir = __DIR__ . '/src/';
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
return;
}
$relativeClass = substr($class, $len);
$file = $baseDir . str_replace('\\', '/', $relativeClass) . '.php';
if (file_exists($file)) {
require $file;
}
});
<?php
// src/Models/User.php
namespace App\Models;
class User
{
public function __construct(private string $name) {}
public function getName(): string
{
return $this->name;
}
}
<?php
// src/Services/UserService.php
namespace App\Services;
use App\Models\User;
class UserService
{
public function greet(User $user): string
{
return 'Olá, ' . $user->getName();
}
}
<?php
// index.php
require 'autoload.php';
use App\Models\User;
use App\Services\UserService;
$user = new User('Maria');
$service = new UserService();
echo $service->greet($user);
Passo a passo
- No
autoload.php, registramos uma função anônima comspl_autoload_register. - A função recebe o nome completo da classe (ex.:
App\Models\User). - Verificamos se o prefixo
App\está no início do nome; se não, retornamos. - Extraímos a parte relativa (
Models\User). - Substituímos
\por/e montamos o caminhosrc/Models/User.php. - Se o arquivo existir, incluímos com
require. - No
index.php, incluímos o autoloader e usamos as classes normalmente.
Por que funciona
O autoloader é chamado automaticamente pelo PHP quando uma classe não é encontrada. Seguindo PSR-4, o namespace reflete a estrutura de diretórios, então o arquivo correto é carregado sob demanda.
Erros comuns
- Não verificar o prefixo: o autoloader tenta carregar classes de outros namespaces e pode incluir arquivos errados.
- Esquecer a barra invertida no prefixo:
$prefix = 'App\';(com uma barra) é inválido; use'App\\'ou'App\\'em strings. - Caminho base sem
__DIR__: usar caminho relativo pode falhar dependendo do diretório de trabalho.
Outra forma de resolver
Com Composer, basta configurar o composer.json e rodar composer dump-autoload. O autoloader gerado é mais robusto e otimizado.
Saída esperada
Olá, Maria