Agora sim podemos testar o suporte a namespace no PHP5.3! Esta versão encontra-se para download apenas no http://snaps.php.net/ que é constantemente atualizada.
Segue abaixo a tradução do README.namespaces que vem junto à ele.
A principal abordagem deste modelo é o problema que temos com nomes muito grandes de classes em bibliotecas no PHP. Não devemos tomar o trabalho de autoloader ou criar modelo de pacotes - somente tornar nomes manuseáveis.
Namespaces são definidos da seguinte forma:
Zend/DB/Connection.php:
<?php
namespace Zend::DB;
class Connection {
}
function connect() {
}
?>
A definição do Namespace faz o seguinte:
Todos os nomes de classes e funções dentro são automaticamente prefixadas
com o nome do namespace. Em namespace, nomes locais sempre tem precedência
sobre nomes globais. Muitos arquivos podem ser usados no mesmo namespace.
A declaração do comando namespace precisa ser o primeiro comando no arquivo.
A única exceção é o comando "declare" que pode ser usado antes.
Toda classe e função em um namespace pode ser referênciado pelo nome completo
- e.g. Zend::DB::Connection ou Zend::DB::connect.
<?php
require 'Zend/Db/Connection.php';
$x = new Zend::DB::Connection;
Zend::DB::connect();
?>
Nome de classe ou namespace pode ser importado:
<?php
require 'Zend/Db/Connection.php';
import Zend::DB;
import Zend::DB::Connection as DbConnection;
$x = new Zend::DB::Connection();
$y = new DB::connection();
$z = new DbConnection();
DB::connect();
?>
comando import somente define nome auxiliares. Ele pode criar apelidos para
namespace ou classe. A simples forma do comando "import A::B::C::D;" é
equivalente a "import A::B::C::D as D;". Comando import pode ser usado
no escopo global (fora de função/classe) e fazer efeito de onde foi definido
até o final do arquivo. É recomendado porém que coloque os imports no início
do arquivo. Comandos import tem efeito somente nos arquivos onde eles aparecem.
O namespace especial "vazio" (prefixo ::) é usado como especificação de
namespace global. Todo nome de classe e função iniciado com :: é interpretado
como global.
<?php
namespace A::B::C;
?>
Uma constante especial __NAMESPACE__ contêm o nome do namespace atual.
Ela pode ser usada para construir nomes para passá-lo como callbacks.
<?php
namespace A::B::C;
function foo() {
}
?>
No namespace global a constante __NAMESPACE__ tem como valor uma string vazia.
Os nomes dentro do namespace são analisados segundo as seguintes regras:
1) todo nome é traduzido durante a compilação de acordo com a atual regra do import.
Então se temos "import A::B::C" então "C::D::e()" é traduzido para "A::B::C::D::e()".
2) classes com nomes não qualificados são traduzidos durante compilação de acordo com
a atual regra do import. Então se nós temos "import A::B::C" então "C::D::e()" é
traduzido para "new A::B::C()".
3) no namespace, chamadas para não qualificadas funções que são definidas no
atual namespace (e é conhecida quando a chamada é analisada) são interpretadas
como chamadas da funções desse namespace.
4) no namespace, chamadas para não qualificadas funções que não são definidas
no atual namespace são resolvidas em run-time. A chamada para função foo()
dentro do namespace (A::B) primeiro tenta encontrar e chama a função do
atual namespace A::B::foo() e se não existir tenta chamar a função interna
foo(). Note que usando foo() no namespace você chama somente a função interna
do PHP, porém usando ::foo() você estará chamando alguma função do namespace global.
5) nomes não qualificados de classes são resolvidos em run-time. E.q. "new Exception()"
primeiro tenta usar (e autoload) a classe do atual namespace e em caso de falha usa
a classe interna do PHP. Note que usando "new A" no namespace, você pode criar classe
para este namespace ou classe interna do PHP, contudo usando "new ::A" você estará criando
uma classe para o namespace global.
6) chamadas para funções qualificadas são resolvidas em run-time. Chamada para "A::B::foo()"
primeiro tenta chamar a função foo() do namespace A::B, então tenta encontrar a classe
"A::B" (__autoload() se necessário) e chama seu método estático foo().
7) Nomes qualificados de classe são interpretados como classe do namespace correspondente.
Então "new A::B::C()" refere-se a class C do namespace A::B.
Exemplos
--------
<?php
namespace A;
foo(); // primeiro tenta chamar "foo" definida no namespace "A"
// então chama a função interna "foo"
::foo(); // chama a função "foo" definida no escopo global
?>
<?php
namespace A;
new B(); // primeiro tenta criar objeto da class "B" definida no namespace "A"
// então cria o objeto da classe interna "B"
new ::B(); // cria objeto da classe "B" definida no escopo global
?>
<?php
namespace A;
new A(); // primeiro tenta criar objeto da classe "A" do namespace "A" (A::A)
// então cria objeto da class interna "A"
?>
<?php
namespace A;
B::foo(); // primeiro tenta chamar a função "foo" do namespace "A::B"
// então chama o método "foo" da classe interna "B"
::B::foo(); // primeiro tenta chamar a função "foo" do namespace "B"
// então chama o método "foo" da classe "B" do escopo global
?>
Quanto ao uso do comando declare, eu verifiquei e não aconteceu o esperado segundo o texto acima. Reportei, e estam verificando.
Até a próxima pessoal!