Os namespaces são um mecanismo utilizado em diversas linguagens de programação que auxilia na organização do aplicativo, permitindo criar objetos com o mesmo nome mas em escopos diferentes. Por exemplo, se você criar uma classe Pessoa para interação com o banco e outra classe Pessoa para métodos adicionais, basta utilizar namespaces diferentes. Uma analogia bem prática são os diretórios do computador, que permitem arquivos com o mesmo nome em diferente diretórios. No final do artigo vou dar um exemplo prático utilizando uma aplicação Laravel 5.
Introdução
Os namespaces foram introduzidos no PHP na versão 5.3.0. O objetivo deles é evitar que tenhamos que criar classes, funções, constantes com nomes “criativos” ou muito grandes para evitar a colisão entre esses nomes. Antes dos namespaces era comum se utilizar prefixos para evitar as colisões, como wp_ (caso do WordPress – em algumas funções) ou sz_ (funções internas da Softerize).
O problema piorava a medida que você precisava incluir bibliotecas de terceiros. A chance de classes ou funções com o mesmo nome era grande. Esse problema foi resolvido com o namespace.
Namespaces
Basicamente o namespace é a definição do escopo de um arquivo. Por definição a declaração do namespace deve ser a primeira coisa em um arquivo PHP (só pode ter comentários ou declare antes).
1 2 3 |
<?php namespace Projeto; // Primeira coisa |
É possível também aninhar namespaces, com vários níveis:
1 2 3 |
<?php namespace Projeto\Funcoes\Banco; |
Se você deixar seu arquivo sem uma definição de namespace, o PHP vai considerar que o seu código está no namespace global, ou seja, o problema das colisões pode acontecer novamente. Claro que se você utilizar bibliotecas decentes no seu projeto, elas possivelmente estão dentro dos seus respectivos namespaces, então o seu projeto só vai ter colisão de nomes caso você mesmo crie objetos com o mesmo nome.
Utilização
Para utilizar namespaces, existem basicamente cinco casos dependendo do que está sendo “utilizado” e de onde se está “utilizando” – vou explicar usando classes:
Classe global utilizada no namespace global
1 2 3 4 5 6 7 |
<?php // arquivo Cliente.php class Cliente { } |
1 2 3 4 |
<?php // arquivo index.php $cliente = new Cliente(); |
Classe com namespace utilizada no namespace global
1 2 3 4 5 6 7 8 |
<?php // arquivo Projeto\Cliente.php namespace Projeto; class Cliente { } |
1 2 3 4 |
<?php // arquivo index.php $cliente = new Projeto\Cliente(); |
Classe global utilizada dentro de um namespace
1 2 3 4 5 6 7 |
<?php // arquivo Cliente.php class Cliente { } |
1 2 3 4 5 |
<?php // arquivo index.php namespace App; $cliente = new \Cliente(); |
Classe com namespace utilizada no mesmo namespace
1 2 3 4 5 6 7 8 |
<?php // arquivo Cliente.php namespace Projeto; class Cliente { } |
1 2 3 4 5 |
<?php // arquivo index.php namespace Projeto; $cliente = new Cliente(); |
Classe com namespace utilizada dentro de outro namespace
1 2 3 4 5 6 7 8 |
<?php // arquivo Cliente.php namespace Projeto; class Cliente { } |
1 2 3 4 5 |
<?php // arquivo index.php namespace App; $cliente = new \Projeto\Cliente(); |
Se você vai utilizar uma classe de um outro namespace muitas vezes no mesmo código, é possível simplificar as chamadas importando e definido apelidos.
Importação e Apelidos
Ao utilizar uma classe ou função de outro namespace temos que utilizar um código do tipo \Meu\Projeto\Com\Namespace\Cliente. Para eliminar este problema podemos importar o namespace no início do arquivo:
1 2 3 4 5 6 7 |
<?php namespace App; use Meu\Projeto\Com\Namespace\Cliente; $cliente = new Cliente(); |
Neste caso ao instanciarmos a classe Cliente, será utilizado a classe definida dentro do namespace. Outra alternativa é criar um apelido (alias) para o namespace desejado:
1 2 3 4 5 6 7 |
<?php namespace App; use Meu\Projeto\Com\Namespace\Cliente as Paciente; $cliente = new Paciente(); |
Exemplo com Laravel
Os frameworks mais modernos utilizam intensamente os namespaces. O Laravel não é exceção. Aqui na Softerize Magazine temos uma série dedicada ao desenvolvimento com Laravel. Não estávamos utilizando namespaces na aplicação, portanto fiz a inclusão dos namespaces como exemplo para o artigo de hoje. Vou reproduzir apenas dois arquivos aqui:
Model de Artigos
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Artigo extends Model { // Relacionamento com usuários public function usuario() { return $this->belongsTo('App\Models\Usuario'); } } |
Controller Principal
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
<?php namespace App\Http\Controllers; use App\Models\Artigo; use Auth; use Input; use Redirect; use View; class HomeController extends Controller { public function getIndex() { $artigos = Artigo::with('usuario')->get(); return View::make('home/index', compact('artigos')); } public function getEntrar() { $titulo = 'Entrar - Desenvolvendo com Laravel'; return View::make('home/entrar', compact('titulo')); } public function postEntrar() { // Opção de lembrar do usuário $remember = false; if(Input::get('remember')) { $remember = true; } // Autenticação if (Auth::attempt(array( 'email' => Input::get('email'), 'password' => Input::get('senha') ), $remember)) { return Redirect::to('artigos'); } else { return Redirect::to('entrar') ->with('flash_error', 1) ->withInput(); } } public function getSair() { Auth::logout(); return Redirect::to('/'); } } |
Para ver o código completo da nossa aplicação visite https://github.com/oscardias/dev-laravel-5. Para visualizar apenas as alterações relacionadas aos namespaces acesse o commit.
Conclusão
Namespaces permitem uma maior organização da nossa aplicação, facilitando a integração dos nossos aplicativos com bibliotecas de terceiros. Os frameworks mais modernos também utilizam namespaces, portanto entender como eles funcionam é essencial. Se você ficou com alguma dúvida, comente.
Referências
Manual do PHP – http://php.net/manual/pt_BR/language.namespaces.rationale.php
Diogo Matheus – http://www.diogomatheus.com.br/blog/php/entendendo-namespaces-no-php/
Daylee Rees – http://daylerees.com/php-namespaces-explained/
Parabéns pelo artigo Oscar. Nem vou dizer que merece um “Oscar” kkkk 😀
Muito bem explicado e objetivo.