English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Basic PHP Tutorial

Advanced PHP Tutorial

PHP & MySQL

PHP Reference Manual

Espaços Nomes PHP

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.

Define namespace

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
?>

Subnamespace

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.

Uso de namespace

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
?>

Namespace e características dinâmicas da linguagem

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"
?>

palavra-chave namespace e constante __NAMESPACE__

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
?>

Uso de namespace: alias/Importação

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
?>

usar espaço de nomes: função global reserva/constante

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";
}
?>

Global space

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;
} 
?>

Namespace order

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:

  1. 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

  2. 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()

  3. 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()

  4. 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()

  5. 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:

    1. Procurar no espaço de nomes atual pelo nome A\B\foo() função

    2. Tente encontrar e chamar global(global) funções no espaço foo()

  6. 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()

    1. 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.

    2. Tente carregar automaticamente a classe A\B\D\E

    3. Procurar no espaço de nomes atualA\B\Cclasse。

    4. Tente carregar automaticamente a classeA\B\C