Nenhum produto encontrado nessa seleção.
Namespaces em PHP são utilizados para encapsular seu código e evitar colisões de nomes de funções, classes, interfaces e constantes.
Neste artigo você vai aprender a criar e utilizar namespaces de maneira adequada.
Então vamos lá.
O que são colisões de nomes?
Se você está iniciando com PHP, provavelmente o termo colisões de nomes deve soar estranho para você. Mas é algo bastante simples, vai por mim.
Quando criamos uma função, classe, constante ou interface, não podemos utilizar o mesmo nome no decorrer de nosso código. Veja um exemplo:
<?php // Uma função sem ações function teste () {} // Mesmo nome: Fatal error: Cannot redeclare teste() function teste () {} ?>
No exemplo acima, a segunda função com o mesmo nome da primeira, irá gerar um erro fatal.
E o mesmo ocorre para constantes:
<?php // Uma uma constante define('constante', true); // Mesmo nome: Notice: Constant constante already defined define('constante', true); ?>
Para classes:
<?php // Uma classe class teste{} // Mesmo nome: Fatal error: Cannot redeclare class teste class teste{} ?>
E para interfaces:
<?php // Uma interface interface teste{} // Mesmo nome: Fatal error: Cannot redeclare class teste interface teste{} ?>
Quando isso acontece, falamos que nosso código tem uma "colisão de nomes", que simplesmente indica que duas porções importantes do código tem o mesmo nome.
Como funcionam os namespaces em PHP?
Namespaces funcionam de maneira idêntica às pastas do seu computador, ou seja, dentro da pasta fotos, posso ter um arquivo chamado de minha_foto.jpg e dentro da pasta documentos também posso ter um arquivo chamado minha_foto.jpg.
Mesmo que o arquivo minha_foto.jpg tenha o mesmo nome nas duas pastas, eles podem ser diferentes e seu conteúdo também pode ser diferente.
Em PHP, você pode ter vários namespaces (que seriam como as pastas) diferentes, e dentro desses namespaces, minhas funções, classes, interfaces e constantes. Se os namespaces forem diferentes, os nomes dos elementos dentro deles podem ser iguais a quaisquer outros nomes que existam em outros namespaces.
Porém, a mesma regra da colisão de nomes se aplica dentro de um namespace, ou seja, você não pode ter dois elementos de mesmo nome dentro de um mesmo namespace.
Como criar um namespace em PHP?
Para criar um namespace em PHP, simplesmente utilize a palavra chave {php}namespace{/php}, veja:
<?php // Define o namespace namespace MeuEspaco; // Uma constante dentro do namespace MeuEspaco define('MinhaConstante', 'Valor da constante'); ?>
No trecho de código acima, criei um namespace chamado MeuEspaco e defini uma constante dentro desse namespace.
Repare que o trecho você deve definir o namespace na primeira linha do seu código, antes de qualquer coisa.
Como definir sub-namespaces em PHP?
Assim como as pastas (detalhado anteriormente) também é possível definir sub-namespaces (com pastas dentro de pastas), assim, você poderá organizar ainda mais seu código.
Para definir um sub-namespace, simplesmente utilize uma barra invertida seguida do nome do sub-namespace.
Veja:
<?php // Define o sub-namespace namespace MeuEspacoSubEspaco; // Uma constante dentro do sub-namespace MeuEspacoSubEspaco define('MinhaConstante', 'Valor da constante'); ?>
Isso seria a mesma coisa que uma subpasta, ou seja, agora minha constante só estará acessível dentro do meu sub-namespace.
Criando vários namespaces em um mesmo arquivo
Namespaces são válidos para um arquivo apenas, porém, você pode definir vários namespaces dentro de um mesmo arquivo. Apesar de não ser recomendado fazer isso, segue um exemplo:
<?php // Define o namespace namespace MeuEspaco; // Uma classe dentro do namespace MeuEspaco class Teste { } // Define outro namespace namespace OutroEspaco; // Uma classe dentro do namespace OutroEspaco class Teste { } ?>
Você também pode utilizar chaves para definir seus namespaces, veja:
<?php // Define o namespace namespace MeuEspaco { // Uma classe dentro do namespace MeuEspaco class Teste { } } // Define outro namespace namespace OutroEspaco { // Uma classe dentro do namespace OutroEspaco class Teste { } } // Código global namespace { // Uma classe global class Teste { } } ?>
Assim você ainda pode misturar o código global, com namespaces diferentes. Perceba que mesmo que eu tenha uma classe declarada três vezes, no trecho acima, são três classes diferentes.
Vamos adicionar ações e executar essas ações para você entender melhor.
<?php // Define o namespace namespace MeuEspaco { // Uma classe dentro do namespace MeuEspaco class Teste { public function __construct () { echo 'Classe está em ' . __NAMESPACE__ . '<br>'; } } } // Define outro namespace namespace OutroEspaco { // Uma classe dentro do namespace OutroEspaco class Teste { public function __construct () { echo 'Classe está em ' . __NAMESPACE__ . '<br>'; } } } // Código global namespace { // Uma classe global class Teste { public function __construct () { echo 'Classe está em ' . __NAMESPACE__ . '<br>'; } } // Instanciando as classes $classe1 = new MeuEspacoTeste(); // Classe está em MeuEspaco $classe2 = new OutroEspacoTeste(); // Classe está em OutroEspaco $classe3 = new Teste(); // Classe está em } ?>
Perceba também, que quando estou trabalhando com namespaces, não posso colocar código fora de um namespace qualquer. No trecho acima, defini os objetos das classes dentro do namespace global.
Observação: Em termos de programação, nunca crie namespaces diferentes, várias classes e nunca crie objetos de classes no mesmo arquivo. Um namespace deve valer para um único arquivo apenas, uma classe deve ser definida em seu próprio arquivo e instanciada fora desse arquivo.
A palavra mágica __NAMESPACE__
A palavra mágica __NAMESPACE__ carrega o nome do namespace que você está trabalhando, veja um exemplo:
<?php // Define o namespace namespace MeuEspacoSubEspacoQualqueCoisa; echo __NAMESPACE__; // MeuEspacoSubEspacoQualqueCoisa ?>
Como utilizar namespaces em PHP
Certo, você aprendeu a criar namespaces e sub-namespaces, mas como vou utilizar isso em meu código?
Simples, para meu exemplo, vou criar dois arquivos diferentes, index.php e outroarquivo.php.
Veja o conteúdo do index.php:
<?php // Define o namespace namespace Index; // Cria uma classe class Classe { // Construtor public function __construct () { echo 'Estou no ' . __NAMESPACE__ . '<br>'; } } // Inclui o outro arquivo include('outroarquivo.php'); ?>
Perceba que estou incluindo o outroarquivo.php no index.php. Teoricamente, se eu tentasse instanciar a classe "Classe" no outro arquivo, daria certo, porém, como defini o namespace no index.php, terei um erro fatal:
<?php // Tento criar a instância: Fatal error: Class 'Classe' not found $classeIndex = new Classe(); ?>
Existem algumas maneiras diferentes para resolver este problema, uma seria definir o namespace Index no outro arquivo; outra seria chamar a classe pelo seu caminho completo, ou seja, namespacenomedaclasse.
Veja ambas as maneiras:
namespacenomedaclasse
<?php // Resultado: Estou no Index $classeIndex = new IndexClasse(); ?>
Definindo o namespace no outro arquivo
<?php // Define o namespace namespace Index; // Resultado: Estou no Index $classeIndex = new Classe(); ?>
Importando namespaces em PHP
Em PHP, você pode "importar" um namespace para outro nome (criar um alias).
Vamos continuar com nossos dois arquivos descritos no subtítulo anterior, não vou mudar o código do index.php, apenas do outroarquivo.php.
<?php // Criando um aliás (atalho) para o namespace use Index as a; // Utilizando o atalho $classe = new aClasse(); ?>
No trecho acima a agora representa meu namespace Index.
Também posso importar quase tudo de outro namespace, menos funções. Veja:
<?php // Criando um aliás (atalho) para a classe "Classe" dentro do // namespace Index use IndexClasse as a; // Utilizando novo nome da classe $classe = new a(); // Resultado: Estou no Index ?>
Só para reforçar, isso só não funciona com funções.
Utilizando o espaço global dentro de um namespace
Dentro de qualquer namespace, é possível sobrescrever as funções nativas do PHP, porém, você ainda terá acesso a elas se utilizar uma barra invertida quando for utilizá-la, veja:
<?php // Define o namespace namespace Index; // Criando uma função chamada trim dentro do namespace function trim($valor) { // Remove espaços do início e do fim da string return preg_replace('/^s+|s+$/', '', $valor); } // Utilizando a função dentro do namespace echo "'" . trim(' Teste de string ') . "'"; // 'Teste de string' // Utilizando a função nativa do PHP no espaço global echo "'" . trim(' Teste de string ') . "'"; // 'Teste de string' ?>
No exemplo acima, criei uma função chama "trim" que sobrescreve a função "trim" nativa do PHP, porém, ainda consegui utilizá-la em meu código, apenas adicionando uma barra invertida.
Isso pode ser feito com qualquer função.
Definindo constantes em namespaces
Se você quiser uma constante em um determinado namespace, simplesmente utilize a palavra chave {php}const{/php}. Veja:
<?php // Define o namespace namespace Index; // Definindo a constante const Constante = 'Valor'; // Mostra o valor da constante echo Constante; // Inclui o outro arquivo include('outroarquivo.php'); ?>
Para acessar o valor da constante fora de um namespace, simplesmente utilize seu nome completo, ou seja, namespacenomedaconstante.
<?php // Acessando a constante do namespace Index echo IndexConstante; ?>
Aprenda mais sobre namespaces em PHP
Se você ainda tem dúvidas, não hesite em questionar nos comentários, e sempre leia o manual do PHP, isso fará você ficar fera na linguagem e na programação, existem altas dicas na contribuição dos usuários.
Veja os links que vão te ajudar:
- Namespaces em PHP – Tudo sobre namespaces no manual do PHP;
- Manual do PHP – Tudo sobre o PHP
E não deixe de seguir todas as aulas do nosso curso gratuito de PHP e de PHP Orientado a Objetos.
Caso tenha dúvidas, pergunte aí abaixo, faremos questão de ajudar.