Regras de resolução de nomes
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
Para efeitos destas regras de resolução, aqui estão algumas definições importantes:
-
Definições de nomes de namespace
- Nome não qualificado
-
Este é um identificador sem separador de namespace, como
Foo
. - Nome qualificado
-
Este é um identificador com separador de namespace, como
Foo\Bar
. - Nome totalmente qualificado
-
Este é um identificador com separador de namespace que começa com um separador de namespace, como
\Foo\Bar
. O namespace\Foo
também é um nome totalmente qualificado. - Nome relativo
-
Este é um identificador que começa com
namespace
, comonamespace\Foo\Bar
.
Os nomes são resolvidos seguindo estas regras de resolução:
-
Nomes totalmente qualificados sempre são resolvidos para o nome sem separador de namespace à esquerda.
Por exemplo,
\A\B
será resolvido paraA\B
. -
Nomes relativos sempre são resolvidos para o nome com
namespace
substituído pelo namespace atual. Se o nome ocorrer no namespace global, o prefixonamespace\
será removido. Por exemplo,namespace\A
dentro do namespaceX\Y
será resolvido paraX\Y\A
. O mesmo nome dentro do namespace global será resolvido paraA
. -
Para nomes qualificados, o primeiro segmento do nome será traduzido conforme a tabela
de importação de classe/namespace atual. Por exemplo, se o namespace
A\B\C
for importado comoC
, o nomeC\D\E
será traduzido paraA\B\C\D\E
. -
Para nomes qualificados, se nenhuma regra de importação se aplicar, o namespace atual será prefixo ao
nome. Por exemplo, o nome
C\D\E
dentro do namespaceA\B
, será resolvido paraA\B\C\D\E
. -
Para nomes não qualificados, o nome será traduzido conforme a tabela de importação atual para o
respectivo tipo de símbolo. Isso significa que nomes semelhantes a classes serão traduzidos conforme a
tabela de importação de classe/namespace, nomes de funções conforme a tabela de importação de funções e
constantes conforme a tabela de importação de constantes. Por exemplo, após a declaração
use A\B\C;
um uso comonew C()
será resolvido para o nomeA\B\C()
. Da mesma forma, após a declaraçãouse function A\B\foo;
um uso comofoo()
será resolvido para o nomeA\B\foo
. -
Para nomes não qualificados, se nenhuma regra de importação se aplicar e o nome se referir a um símbolo de classe,
o namespace atual será prefixo. Por exemplo
new C()
dentro do namespaceA\B
será resolvido para o nomeA\B\C
. -
Para nomes não qualificados, se nenhuma regra de importação se aplicar e o nome se referir a uma função ou constante
e o código estiver fora do namespace global, o nome será resolvido em tempo de execução.
Supondo que o código esteja no namespace
A\B
, é assim que uma chamada para a funçãofoo()
será resolvida:-
Procura pela função no namespace atual:
A\B\foo()
. -
Tenta encontrar e chamar a função global
foo()
.
-
Procura pela função no namespace atual:
Example #1 Resoluções de nomes ilustradas
<?php
namespace A;
use B\D, C\E as F;
// chamadas de funções
foo(); // primeiro tenta chamar "foo" definida no namespace "A"
// então chama a função global "foo"
\foo(); // chama a função "foo" definida no escopo global
minha\foo(); // chama a função "foo" definida no namespace "A\minha"
F(); // primeiro tenta chamar "F" definida no namespace "A"
// e então chama a função global "F"
// referências de classe
new B(); // cria um objeto da classe "B" definida no namespace "A"
// se não for encontrada, tenta carregar automaticamente a classe "A\B"
new D(); // usando regras de importação, cria um objeto da classe "D" definida no namespace "B"
// se não for encontrada, tenta carregar automaticamente a classe "B\D"
new F(); // usando regras de importação, cria um objeto da classe "E" definida no namespace "C"
// se não for encontrada, tenta carregar automaticamente a classe "C\E"
new \B(); // cria um objeto da classe "B" definida no escopo global
// se não for encontrada, tenta carregar automaticamente a classe "B"
new \D(); // cria um objeto da classe "D" definida no escopo global
// se não for encontrado, tenta carregar automaticamente a classe "D"
new \F(); // cria um objeto da classe "F" definida no escopo global
// se não for encontrada, tenta carregar automaticamente a classe "F"
// métodos estáticos/funções de namespace de outro namespace
B\foo(); // chama a função "foo" do namespace "A\B"
B::foo(); // chama o método "foo" da classe "B" definida no namespace "A"
// se a classe "A\B" não for encontrada, tenta carregar automaticamente a classe "A\B"
D::foo(); // usando regras de importação, chama o método "foo" da classe "D" definida no namespace "B"
// se a classe "B\D" não for encontrada, tenta carregar automaticamente a classe "B\D"
\B\foo(); // chama a função "foo" do namespace "B"
\B::foo(); // chama o método "foo" da classe "B" do escopo global
// se a classe "B" não for encontrada, tenta carregar automaticamente a classe "B"
// métodos estáticos/funções de namespace do namespace atual
A\B::foo(); // chama o método "foo" da classe "B" do namespace "A\A"
// se a classe "A\A\B" não for encontrada, tenta carregar automaticamente a class "A\A\B"
\A\B::foo(); // chama o método "foo" da classe "B" do namespace "A"
// se a classe "A\B" não for encontrada, tenta carregar automaticamente a classe "A\B"
?>