Namespaces
Esta aula aborda namespaces em PHP, incluindo declaração, importação com 'use', criação de aliases e organização de código. Ao final, você será capaz de estruturar projetos PHP de forma modular e evitar conflitos de nomes.
Namespaces são uma funcionalidade essencial do PHP para organizar classes, interfaces, funções e constantes em grupos lógicos, evitando conflitos de nomes entre diferentes partes de um projeto ou bibliotecas de terceiros. Introduzidos no PHP 5.3, os namespaces permitem que você crie código mais modular e reutilizável, especialmente em projetos grandes ou ao integrar múltiplos pacotes.
Nesta aula, exploraremos como declarar namespaces, como importar símbolos usando a palavra-chave use, como criar aliases para nomes longos e como organizar seu código de forma eficiente. Vamos usar exemplos práticos para cada conceito.
namespace
Um namespace é um contêiner abstrato que agrupa itens relacionados. A declaração de namespace deve ser a primeira instrução no arquivo PHP (antes de qualquer código não namespace, exceto declare). A sintaxe é namespace NomeDoNamespace;. Você pode usar subnamespaces separando por barra invertida (\), como App\Model.
Quando você define uma classe dentro de um namespace, ela é referenciada pelo nome completo (fully qualified name) que inclui o namespace. Por exemplo, App\Model\User. Isso evita colisões se outro pacote também tiver uma classe User.
<?php
namespace App\Model;
class User {
public function greet() {
return "Olá do namespace App\\Model!";
}
}
?>Para usar essa classe fora do namespace, você precisa referenciá-la pelo nome completo: $user = new \App\Model\User();. O namespace global (sem nome) é acessado prefixando com uma barra invertida, como \DateTime.
use
A palavra-chave use permite importar um namespace ou classe para o escopo atual, evitando escrever o nome completo toda vez. A importação é feita no topo do arquivo, após a declaração de namespace (se houver). Você pode importar classes, interfaces, funções e constantes.
Exemplo de importação de classe: use App\Model\User;. Depois disso, você pode usar apenas User no código. Para funções e constantes, use use function e use const respectivamente.
<?php
namespace App\Controller;
use App\Model\User;
use function App\Utils\formatDate;
use const App\Config\MAX_ITEMS;
class UserController {
public function show() {
$user = new User(); // Resolve para App\Model\User
echo formatDate(time());
echo MAX_ITEMS;
}
}
?>É possível importar múltiplos itens separando por vírgula: use App\Model\User, App\Model\Admin;. Mas a prática recomendada é usar uma declaração por linha para melhor legibilidade.
Aliases
Aliases permitem renomear um nome importado para evitar conflitos ou encurtar nomes muito longos. A sintaxe é use NomeOriginal as Alias;. Você pode criar aliases para classes, funções e constantes.
Por exemplo, se você está usando duas bibliotecas que têm uma classe Logger, pode criar aliases diferentes:
<?php
use MyFramework\Logger as FrameworkLogger;
use ThirdParty\Logger as ThirdPartyLogger;
$logger1 = new FrameworkLogger();
$logger2 = new ThirdPartyLogger();
?>Aliases também são úteis para encurtar nomes de classes muito longos, como use Very\Long\Namespace\ClassName as Short;. Lembre-se que o alias é válido apenas no escopo do arquivo onde é declarado.
Organização de código
Para organizar projetos PHP com namespaces, siga a convenção PSR-4, que mapeia namespaces para diretórios. Por exemplo, o namespace App\Model corresponde ao diretório src/Model. Cada classe fica em seu próprio arquivo com o mesmo nome da classe. Isso facilita o autoloading.
Exemplo de estrutura de diretórios:
projeto/
├── src/
│ ├── Model/
│ │ └── User.php
│ ├── Controller/
│ │ └── UserController.php
│ └── Utils/
│ └── Validator.php
├── public/
│ └── index.php
└── composer.jsonNo arquivo User.php, o namespace é App\Model. O autoloader (como o do Composer) carrega a classe automaticamente quando ela é usada. Para configurar o Composer, adicione no composer.json:
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}Depois, execute composer dump-autoload. Agora, no index.php, você pode usar:
<?php
require_once 'vendor/autoload.php';
use App\Model\User;
use App\Controller\UserController;
$user = new User();
echo $user->greet();
?>Essa organização mantém o código limpo, modular e fácil de manter.
Boas práticas
- Use namespaces consistentes com a estrutura de diretórios (PSR-4).
- Evite importar múltiplas classes com aliases desnecessários; use apenas quando houver conflito.
- Prefira importar classes individualmente em vez de usar
usecom curinga (não suportado em PHP). - Nunca declare namespaces em arquivos que contenham código procedural misturado; separe bem.
Referências
- Manual do PHP: Namespaces
- PSR-4: Autoloading Standard
- PHP: Rationale for Namespaces
- PHP: Importing and Aliasing
- Composer: Autoloading
Exercícios
Crie um namespace
App\Utilscom uma funçãoformatDateque retorna a data atual formatada como 'd/m/Y'. Em seguida, importe e use essa função em um arquivo separado.✓ Resposta:// src/Utils/helpers.php <?php namespace App\Utils; function formatDate($timestamp = null) { $timestamp = $timestamp ?? time(); return date('d/m/Y', $timestamp); } ?> // index.php <?php require_once 'src/Utils/helpers.php'; use function App\Utils\formatDate; echo formatDate(); // Exemplo: 15/03/2025 ?>Importe a classe
DateTimedo namespace global e crie um aliasDT. Instancie e exiba a data atual.✓ Resposta:<?php use DateTime as DT; $dt = new DT(); echo $dt->format('Y-m-d H:i:s'); ?>Declare duas classes com o mesmo nome
Loggerem namespaces diferentes:App\LogeVendor\Log. No código principal, importe ambas usando aliases e instancie cada uma.✓ Resposta:// src/Log/Logger.php <?php namespace App\Log; class Logger { public function log($msg) { echo "App Log: $msg\n"; } } ?> // vendor/Vendor/Log/Logger.php <?php namespace Vendor\Log; class Logger { public function log($msg) { echo "Vendor Log: $msg\n"; } } ?> // index.php <?php require_once 'src/Log/Logger.php'; require_once 'vendor/Vendor/Log/Logger.php'; use App\Log\Logger as AppLogger; use Vendor\Log\Logger as VendorLogger; $appLogger = new AppLogger(); $vendorLogger = new VendorLogger(); $appLogger->log('teste'); $vendorLogger->log('teste'); ?>Organize as seguintes classes em namespaces seguindo PSR-4:
User(model),UserController(controller). Crie a estrutura de diretórios e o autoload com Composer. Escreva o código de exemplo que instancia um User.✓ Resposta:projeto/ ├── src/ │ ├── Model/ │ │ └── User.php │ └── Controller/ │ └── UserController.php ├── public/ │ └── index.php └── composer.json// src/Model/User.php <?php namespace App\Model; class User { public function getName() { return "João"; } } ?> // src/Controller/UserController.php <?php namespace App\Controller; use App\Model\User; class UserController { public function show() { $user = new User(); return $user->getName(); } } ?> // composer.json { "autoload": { "psr-4": { "App\\": "src/" } } } // public/index.php <?php require_once '../vendor/autoload.php'; use App\Model\User; $user = new User(); echo $user->getName(); ?>Crie um namespace
App\Configcom uma constanteMAX_ITEMSigual a 50. Importe-a em outro arquivo usandouse conste exiba seu valor.✓ Resposta:// src/Config/constants.php <?php namespace App\Config; define('App\Config\MAX_ITEMS', 50); // Ou use const: const MAX_ITEMS = 50; ?> // index.php <?php require_once 'src/Config/constants.php'; use const App\Config\MAX_ITEMS; echo MAX_ITEMS; // 50 ?>