W3docs

Entendendo os Namespaces do PHP

Os namespaces do PHP agrupam classes, funções e constantes em uma estrutura lógica para evitar conflitos de nomes em projetos modernos.

Um namespace é uma forma de agrupar classes, interfaces, funções e constantes relacionadas sob um único nome lógico. Pense nele como pastas no seu disco: dois arquivos chamados index.php podem coexistir desde que estejam em pastas diferentes. Da mesma forma, duas classes chamadas User podem coexistir desde que estejam em namespaces diferentes.

Sem namespaces, todos os nomes compartilham um único espaço global. No momento em que seu projeto e uma biblioteca de terceiros definem uma classe chamada Logger ou Router, o PHP lança um erro fatal Cannot declare class. Os namespaces são a solução padrão para esse problema e são a base do autoloading do Composer (o padrão PSR-4) utilizado por praticamente todos os pacotes PHP modernos.

Por Que os Namespaces São Importantes

  • Evitar colisões de nomes. Dois trechos de código podem usar o mesmo nome de classe ou função desde que estejam em namespaces diferentes, então seu código nunca conflita com o código de uma biblioteca.
  • Organizar bases de código grandes. Os namespaces espelham a estrutura de pastas, tornando óbvio onde uma classe está (App\Service\Mailer está em app/Service/Mailer.php).
  • Habilitar o autoloading. O PSR-4 mapeia um prefixo de namespace para um diretório, permitindo que o Composer carregue classes sob demanda sem instruções require manuais.

Definindo um Namespace

Declare um namespace com a palavra-chave namespace. Ela deve ser a primeira instrução no arquivo (apenas uma linha declare(strict_types=1) pode vir antes). Os nomes de namespace usam uma barra invertida (\) para separar níveis:

<?php
namespace App\Service;

class Mailer
{
    public function send(string $to): string
    {
        return "Mail sent to {$to}";
    }
}

Tudo declarado abaixo da linha namespace — a classe Mailer — agora vive em App\Service. Seu nome completamente qualificado é App\Service\Mailer.

Referenciando Itens com Namespace

Existem três formas de se referir a um nome de outro namespace.

Um nome completamente qualificado começa com um \ inicial e nomeia o item a partir da raiz global — é inequívoco em qualquer lugar:

<?php
$mailer = new \App\Service\Mailer();

Um nome qualificado é relativo ao namespace atual, então Service\Mailer dentro do namespace App resolve para App\Service\Mailer. Um nome sem nenhuma barra invertida é não qualificado e é buscado primeiro no namespace atual.

Importando Com use

Escrever o caminho completo toda vez é tedioso. A palavra-chave use importa um nome no arquivo atual para que você possa referenciá-lo pelo seu nome abreviado:

<?php
use App\Service\Mailer;

$mailer = new Mailer();   // resolves to App\Service\Mailer

Criando Aliases Com as

Quando duas classes importadas compartilham um nome abreviado, dê a uma delas um alias com as para desambiguar:

<?php
use App\Service\Mailer;
use Vendor\Mail\Mailer as VendorMailer;

$a = new Mailer();        // App\Service\Mailer
$b = new VendorMailer();  // Vendor\Mail\Mailer

Importando Funções e Constantes

use importa classes por padrão. Para importar uma função ou uma constante, adicione a palavra-chave function ou const:

<?php
use function App\Helpers\format_price;
use const App\Config\TAX_RATE;

Atenção: Funções Internas Precisam de Barra Invertida Inicial

Dentro de um namespace, um nome de função ou classe não qualificado é resolvido primeiro contra o namespace atual. Para funções internas, o PHP recorre automaticamente à versão global, mas para classes internas ele não faz isso. Portanto, referenciar classes principais como Exception, DateTime ou PDO requer uma barra invertida inicial (ou uma instrução use):

<?php
namespace App\Service;

// Wrong: PHP looks for App\Service\Exception, which doesn't exist.
// throw new Exception('boom');

// Right: leading backslash points to the global class.
throw new \Exception('boom');

Um padrão comum e legível é importar a classe principal no topo do arquivo:

<?php
namespace App\Service;

use Exception;

throw new Exception('boom');   // now the short name works

Um Exemplo Completo

Este script único e executável define dois namespaces e usa ambos — mostrando como o mesmo nome abreviado de classe pode existir em dois lugares sem conflito:

<?php
namespace App\Billing {
    class Invoice
    {
        public function label(): string
        {
            return 'Billing invoice';
        }
    }
}

namespace App\Shipping {
    class Invoice
    {
        public function label(): string
        {
            return 'Shipping invoice';
        }
    }
}

namespace Main {
    use App\Billing\Invoice;
    use App\Shipping\Invoice as ShippingInvoice;

    $billing  = new Invoice();
    $shipping = new ShippingInvoice();

    echo $billing->label() . "\n";
    echo $shipping->label() . "\n";
}

Saída:

Billing invoice
Shipping invoice

A sintaxe namespace Foo { ... } com chaves é usada apenas para colocar múltiplos namespaces em um arquivo (útil para exemplos independentes). Em projetos reais, você coloca um namespace por arquivo e depende do autoloading do Composer.

Namespaces e Autoloading (PSR-4)

Na prática, você raramente escreve os limites de namespace manualmente para cada arquivo — o Composer faz a configuração. Um mapeamento PSR-4 no composer.json vincula um prefixo de namespace a uma pasta:

{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

Com isso configurado, a classe App\Service\Mailer é carregada automaticamente de src/Service/Mailer.php na primeira vez que você a referenciar — sem necessidade de include ou require manuais.

Resumo

  • Um namespace agrupa classes, interfaces, funções e constantes para evitar colisões de nomes e organizar o código.
  • Declare-o com namespace App\Service; como primeira instrução no arquivo.
  • Referencie itens pelo nome completamente qualificado (\App\Service\Mailer) ou, mais comumente, importe-os com use e use o nome abreviado.
  • Crie aliases para nomes conflitantes com as e lembre-se de prefixar classes globais como \Exception com uma barra invertida dentro de um namespace.
  • O autoloading PSR-4 mapeia um prefixo de namespace para um diretório, que é como todos os pacotes Composer são carregados.

Prática

Prática
Quais são as finalidades dos namespaces do PHP?
Quais são as finalidades dos namespaces do PHP?
Was this page helpful?