English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
PHP namespaces (namespace) are in PHP 5.3added, if you have learned C# and Java, namespaces are not a new thing. However, in PHP, they still have significant importance.
PHP namespaces can solve the following two types of problems:
User-written code and PHP internal classes/Functions/Constants or third-party classes/Functions/Name conflicts between constants
Create an alias (or short) name for a very long identifier name (usually defined to alleviate the first-class problem) to improve the readability of the source code.
By default, all constants, class, and function names are placed in the global space, just as PHP supported namespaces before.
Namespaces are declared using the namespace keyword. If a file contains a namespace, it must be declared before all other code. The syntax format is as follows;
<?php // Define code in the 'MyProject' namespace namespace MyProject; // ... code ...
You can also define different namespace code in the same file, such as:
<?php namespace MyProject; const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } namespace AnotherProject; const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } ?>
It is not recommended to define multiple namespaces in a single file using this syntax. It is recommended to use the following syntax with curly braces.
<?php namespace MyProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } namespace AnotherProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } ?>
To combine global code outside of a namespace with code within a namespace, you must use the syntax with curly braces. Global code must be enclosed in a namespace statement without a name and curly braces, for example:
<?php namespace MyProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } namespace { // Código global session_start(); $a = MyProject\connect(); echo MyProject\Connection::start(); } ?>
Before declaring a namespace, the only valid code is the declare statement used to define the encoding of the source file. No non-PHP code, including whitespace, can appear before the namespace declaration.
<?php declare(encoding='UTF)-8'); //Definir múltiplos namespaces e código não contido em namespace namespace MyProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } namespace { // Código global session_start(); $a = MyProject\connect(); echo MyProject\Connection::start(); } ?>
O seguinte código gerará um erro de sintaxe:
<html> <?php namespace MyProject; // Se o <html> aparecer antes do namespace, será gerado um erro fatal - O namespace deve ser a primeira linha do script ?>
Como as relações entre diretórios e arquivos, o namespace do PHP também permite especificar o nome do namespace hierárquico. Portanto, o nome do namespace pode ser definido de maneira hierárquica:
<?php namespace MyProject\Sub\Level; //Declarar namespace hierárquico const CONNECT_OK = 1; class Connection { /* ... */ } function Connect() { /* ... */ } ?>
O exemplo acima criou a constante MyProject\Sub\Level\CONNECT_OK, a classe MyProject\Sub\Level\Connection e a função MyProject\Sub\Level\Connect.
O nome da classe em namespace do PHP pode ser referenciado de três maneiras:
Nome não qualificado, ou nome da classe sem prefixoPor exemplo, $a = new foo(); ou foo::staticmethod();. Se o namespace atual é currentnamespace, foo será interpretado como currentnamespace\foo. Se o código que usa foo é global, não contido em nenhum namespace, foo será interpretado como foo. Aviso: Se a função ou constante não estiver definida no namespace, o nome não qualificado da função ou constante será interpretado como nome da função ou constante global.
Nome qualificado, ou nome contendo prefixoPor exemplo, $a = new subnamespace\foo(); ou subnamespace\foo::staticmethod();. Se o namespace atual é currentnamespace, foo será interpretado como currentnamespace\subnamespace\foo. Se o código que usa foo é global, não contido em nenhum namespace, foo será interpretado como subnamespace\foo.
Nome completo, ou nome que contém o operador de prefixo globalPor exemplo, $a = new \currentnamespace\foo(); ou \currentnamespace\foo::staticmethod();. Neste caso, foo sempre é analisado como o nome literal (literal name) currentnamespace\foo no código.
A seguir está um exemplo de uso desses três métodos:
file1Código do arquivo .php
<?php namespace Foo\Bar\subnamespace; const FOO = 1; function foo() {} class foo { function static staticmethod() {} } ?>
file2Código do arquivo .php
<?php namespace Foo\Bar; include 'file1.php'; const FOO = 2; function foo() {} class foo { function static staticmethod() {} } /* Nome curto */ foo(); // Analisa-se a função Foo\Bar\foo foo::staticmethod(); // Analisa-se a classe Foo\Bar\foo, método static echo FOO; // Analisa-se a constante Foo\Bar\FOO /* Nome curto */ subnamespace\foo(); // Analisa-se a função Foo\Bar\subnamespace\foo subnamespace\foo::staticmethod(); // Analisa-se a classe Foo\Bar\subnamespace\foo, // e os métodos da classe static echo subnamespace\FOO; // Analisa-se a constante Foo\Bar\subnamespace\FOO /* Nome completo */ \Foo\Bar\foo(); // Analisa-se a função Foo\Bar\foo \Foo\Bar\foo::staticmethod(); // Analisa-se a classe Foo\Bar\foo, bem como os métodos da classe static echo \Foo\Bar\FOO; // Analisa-se a constante Foo\Bar\FOO ?>
Atenção, para acessar qualquer classe, função ou constante global, pode-se usar o nome completo, por exemplo \strlen() ou \Exception ou \INI_ALL.
Acesso a classes, funções e constantes globais dentro do espaço de nomes:
<?php namespace Foo; function strlen() {} const INI_ALL = ; 3; class Exception {} $a = \strlen('hi'); // Chamada da função global strlen $b = \INI_ALL; // Acesso à constante global INI_ALL $c = new \Exception('error'); // Exemplificação da classe global Exception ?>
A implementação do namespace no PHP é influenciada pela dinâmica do próprio idioma. Portanto, se precisar converter o código a seguir para um namespace, acesse os elementos dinamicamente.
example1Código do arquivo .php:
<?php class classname { function __construct() { echo __METHOD__, '\n'; } } function funcname() { echo __FUNCTION__, '\n'; } const constname = 'global'; $a = 'classname'; $obj = new $a; // prints classname::__construct $b = 'funcname'; $b(); // prints funcname echo constant('constname'), '\n'; // prints global ?>
É necessário usar o nome completo (inclusive o nome do namespace da classe). Note que, devido à característica dinâmica dos nomes de classes, funções ou constantes, o caractere de escape inicial não é necessário, pois o nome completo e o nome completo delimitado não diferem.
Acesso dinâmico aos elementos do namespace
<?php namespace namespacename; class classname { function __construct() { echo __METHOD__, '\n'; } } function funcname() { echo __FUNCTION__, '\n'; } const constname = 'namespaced'; include 'example1.php'; $a = 'classname'; $obj = new $a; // Saída classname::__construct $b = 'funcname'; $b(); // Saída nome da função echo constant('constname'), '\n'; // Saída global /* Se usar aspas duplas, a forma de usar é "\\namespacename\\classname"*/ $a = '\namespacename\classname'; $obj = new $a; // Saída namespacename\classname::__construct $a = 'namespacename\classname'; $obj = new $a; // Saída namespacename\classname::__construct $b = 'namespacename\funcname'; $b(); // saída "namespacename\funcname" $b = 'namespacename\funcname'; $b(); // saída "namespacename\funcname" echo constante('\namespacename\constname'), '\n'; // saída "namespaced" echo constante('namespacename\constname'), '\n'; // saída "namespaced" ?>
O PHP suporta dois métodos abstratos para acessar elementos dentro da namespace atual, a constante __NAMESPACE__ e a palavra-chave namespace.
O valor da constante __NAMESPACE__ é uma string que contém o nome da namespace atual. No global, código que não está dentro de nenhuma namespace, ele contém uma string vazia.
__NAMESPACE__ exemplo, código dentro do namespace
<?php namespace MyProject; echo '"', __NAMESPACE__, '"'; // saída "MyProject" ?>
__NAMESPACE__ exemplo, código global
<?php echo '"', __NAMESPACE__, '"'; // saída "" ?>
A constante __NAMESPACE__ é muito útil ao criar nomes dinamicamente, por exemplo:
Uso de __NAMESPACE__ para criar nomes dinamicamente
<?php namespace MyProject; função get($classname) { $a = __NAMESPACE__ . '\\' . $classname; retorna new $a; } ?>
A palavra-chave namespace pode ser usada para acessar explicitamente elementos da namespace atual ou de subnamespaces. Ela é equivalente ao operador self dentro de uma classe.
operador namespace, código dentro do namespace
<?php namespace MyProject; use blah\blah como mine; // veja "Usando namespaces: importando/aliasing" blah\mine(); // chama função blah\blah\mine() namespace\blah\mine(); // chama função MyProject\blah\mine() namespace\func(); // chama função MyProject\func() namespace\sub\func(); // chama função MyProject\sub\func() namespace\cname::method(); // chama método estático "method" da classe MyProject\cname $a = new namespace\sub\cname(); // instancia objeto da classe MyProject\sub\cname $b = namespace\CONSTANT; // Atribui o valor da constante MyProject\CONSTANT para $b ?>
Operador namespace, código global
<?php namespace\func(); // Chama a função func() namespace\sub\func(); // Chama a função sub\func() namespace\cname::method(); // Chama o método estático "method" da classe cname $a = new namespace\sub\cname(); // Instancia um objeto da classe sub\cname $b = namespace\CONSTANT; // Atribui o valor da constante CONSTANT para $b ?>
O PHP suporta duas maneiras de usar alias ou importação: usar alias para nomes de classes ou usar alias para nomes de namespaces.
No PHP, o alias é implementado pelo operador use. Abaixo está um exemplo de uso de todos os três tipos possíveis de importação:
1、Uso do operador use para importação/Uso de alias
<?php namespace foo; use My\Full\Classname as Another; // O exemplo a seguir é equivalente a use My\Full\NSname as NSname use My\Full\NSname; // Importar uma classe global use \ArrayObject; $obj = new namespace\Another; // Exemplificar o objeto foo\Another $obj = new Another; // Exemplificar o objeto My\Full\Classname NSname\subns\func(); // Chamar a função My\Full\NSname\subns\func $a = new ArrayObject(array(1)); // Exemplificar o objeto ArrayObject // Se não usar "use \ArrayObject", exemplificar um objeto foo\ArrayObject ?>
2、Várias declarações use em uma linha
<?php use My\Full\Classname as Another, My\Full\NSname; $obj = new Another; // Exemplificar o objeto My\Full\Classname NSname\subns\func(); // Chamar a função My\Full\NSname\subns\func ?>
A operação de importação é executada na compilação, mas os nomes de classes, funções ou constantes dinâmicos não são.
3、Importação e nome dinâmico
<?php use My\Full\Classname as Another, My\Full\NSname; $obj = new Another; // Exemplificar um objeto My\Full\Classname $a = 'Another'; $obj = new $a; // instanciar um objeto Another ?>
Além disso, a operação de importação afeta apenas nomes não qualificados e qualificados. Os nomes completos, devido a serem determinados, não são afetados pela importação.
4、importação e nome completo
<?php use My\Full\Classname as Another, My\Full\NSname; $obj = new Another; // instanciar a classe My\Full\Classname $obj = new \Another; // instanciar a classe Another $obj = new Another\thing; // instanciar a classe My\Full\Classname\thing $obj = new \Another\thing; // instanciar a classe Another\thing ?>
Em um espaço de nomes, quando o PHP encontra um nome de classe, função ou constante não qualificado, ele usa diferentes estratégias de prioridade para resolver o nome. O nome da classe sempre é resolvido para o nome no espaço de nomes atual. Portanto, ao acessar classes internas ou não incluídas no espaço de nomes, é necessário usar o nome completo, por exemplo:
1、acesso a classe global no espaço de nomes
<?php namespace A\B\C; class Exception extends \Exception {} $a = new Exception('hi'); // $a é um objeto da classe A\B\C\Exception $b = new \Exception('hi'); // $b é um objeto da classe Exception $c = new ArrayObject; // erro fatal, não encontrado a classe A\B\C\ArrayObject ?>
Para funções e constantes, se não existir a função ou constante no espaço de nomes atual, o PHP recorrerá ao espaço de nomes global para a função ou constante.
2、função global reserva no espaço de nomes/constante
<?php namespace A\B\C; const E_ERROR = 45; function strlen($str) { return \strlen($str) - 1; } echo E_ERROR, "\n"; // output ""45" echo INI_ALL, "\n"; // output ""7" - usar constante global INI_ALL echo strlen('hi'), "\n"; // output ""1" if (is_array('hi')) { // output "não é array" echo "é array\n"; } else { echo "não é array\n"; } ?>
If no namespace is defined, all class and function definitions are in the global space, just like before the introduction of the namespace concept in PHP. Adding the prefix \ to the name indicates that the name is in the global space, even if the name is located in another namespace.
Use global space notation
<?php namespace A\B\C; /* This function is A\B\C\fopen */ function fopen() { /* ... */ $f = \fopen(...); // Call the global fopen function return $f; } ?>
Since the introduction of namespaces, the most easily made mistake should be when using classes, what is the search path for this class.
<?php namespace A; use B\D, C\E as F; // Function call foo(); // Firstly, try to call the function foo() defined in the namespace "A" // Try to call the global function "foo" again \foo(); // Call the global function "foo" my\foo(); // Call the function "foo" defined in the namespace "A\my" F(); // Firstly, try to call the function "F" defined in the namespace "A" // Try to call the global function "F" again // Class reference new B(); // Create an object of the class "B" defined in the namespace "A" // If not found, try to automatically load the class "A\B" new D(); // Using import rules, create an object of the class "D" defined in the namespace "B" // If not found, try to automatically load the class "B\D" new F(); // Using import rules, create an object of the class "E" defined in the namespace "C" // If not found, try to automatically load the class "C\E" new \B(); // Create an object of the class "B" defined in the global space // If not found, try to automatically load the class "B" new \D(); // Create an object of the class "D" defined in the global space // If not found, try to automatically load the class "D" new \F(); // Create an object of the class "F" defined in the global space // If not found, try to automatically load the class "F" // Call a static method or namespace function in another namespace B\foo(); // Call the function "foo" in the namespace "A\B" B::foo(); // Chamar o método "foo" da classe "B" definida no espaço de nomes "A" // If the class "A\B" is not found, try to automatically load the class "A\B" D::foo(); // Using import rules, call the "foo" method of the class "D" defined in the namespace "B" // Se a classe "B\D" não for encontrada, tentar carregar automaticamente a classe "B\D" \B\foo(); // Chamar a função "foo" no espaço de nomes "B" \B::foo(); // Chamar o método "foo" da classe "B" no espaço global // Se a classe "B" não for encontrada, tentar carregar automaticamente a classe "B" // Métodos estáticos ou funções no espaço de nomes atual A\B::foo(); // Chamar o método "foo" da classe "B" definida no espaço de nomes "A\A" // Se a classe "A\A\B" não for encontrada, tentar carregar automaticamente a classe "A\A\B" \A\B::foo(); // Chamar o método "foo" da classe "B" definida no espaço de nomes "A" // Se a classe "A\B" não for encontrada, tentar carregar automaticamente a classe "A\B" ?>
As regras de análise de nomes são as seguintes:
Chamadas de funções, classes e constantes completamente qualificadas são analisadas no tempo de compilação. Por exemplo new \A\B é analisado como classe A\B。
Todos os nomes não qualificados e qualificados (não nomes completos) são convertidos no tempo de compilação com base nas regras de importação atuais. Por exemplo, se o espaço de nomes A\B\C é importado como Cserá convertida para C\D\e() A chamada A\B\C\D\e()。
No interior do espaço de nomes, todos os nomes qualificados que não foram convertidos com base nas regras de importação são adicionados o nome do espaço de nomes atual à sua frente. Por exemplo, no espaço de nomes A\B Chamadas internas C\D\e()então C\D\e() será convertido para A\B\C\D\e() 。
Nomes de classes não qualificados são convertidos no tempo de compilação com base nas regras de importação atuais (usando nomes completos em vez de nomes curtos). Por exemplo, se o espaço de nomes A\B\C Importado como C, então new C() é convertida para new A\B\C() 。
No interior do espaço de nomes (por exemplo A\B), chamadas de funções não qualificadas são analisadas no tempo de execução. Por exemplo, para a função foo() A chamada é analisada da seguinte forma:
Procurar no espaço de nomes atual pelo nome A\B\foo() função
Tente encontrar e chamar global(global) funções no espaço foo()。
no espaço de nomes (por exemploA\BChamadas internas a nomes não qualificados ou classes qualificadas (não nomes completos) são analisadas no tempo de execução. Abaixo está a chamada new C() e new D\E() O processo de análise: new C()A análise: new D\E()A análise: Para referenciar classes globais no espaço de nomes global, é necessário usar o nome completo. new \C()。
Adicionar o nome do espaço de nomes atual à frente do nome da classe torna-se:A\B\D\Ee então procurar essa classe.
Tente carregar automaticamente a classe A\B\D\E。
Procurar no espaço de nomes atualA\B\Cclasse。
Tente carregar automaticamente a classeA\B\C。