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

Basic PHP Tutorial

Advanced PHP Tutorial

PHP & MySQL

PHP Reference Manual

PHP-Namespace

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 a significant meaning.

PHP namespaces can solve the following two types of problems:

  • User-written code versus 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 keyword namespace. If a file contains a namespace, it must be declared before all other code. The syntax format is as follows;

<?php  
// Define code within the 'MyProject' namespace  
namespace MyProject;  
 
// ... code ...

You can also define different namespace code within 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 within 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, the syntax using curly braces must be used. Global code must be enclosed within a namespace statement without a name and curly braces, for example:

<?php
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}
namespace { // Globaler Code
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>

Before the declaration of the 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 declaration of the namespace.

<?php
declare(encoding='UTF)-8); //Definition mehrerer Namespaces und Codes, die nicht in Namespaces enthalten sind
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}
namespace { // Globaler Code
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>

Der folgende Code führt zu einem Syntaxfehler:

<html>
<?php
namespace MyProject; // Ein "<html>" vor dem Namespace führt zu einem fatalen Fehler - Der Namespace muss die erste Anweisung im Skript sein
?>

Unternamespace

Ähnlich wie das Verhältnis zwischen Verzeichnissen und Dateien, ermöglichen es die Namensräume in PHP, hierarchische Namensräume zu spezifizieren. Daher kann der Name des Namensraums auf hierarchische Weise definiert werden:

<?php
namespace MyProject\Sub\Level;  //Erklärung eines hierarchischen einzelnen Namensraums
const CONNECT_OK = 1;
class Connection { /* ... */ }
function Connect() { /* ... */  }
?>

Der obige Beispielcode erstellt die Konstante MyProject\Sub\Level\CONNECT_OK, die Klasse MyProject\Sub\Level\Connection und die Funktion MyProject\Sub\Level\Connect.

Namespace-Nutzung

Der Klassename in einem PHP-Namespace kann auf drei Arten referenziert werden:

  • Nicht eingeschränkter Name, oder Name der Klasse ohne Präfix.Zum Beispiel $a = new foo(); oder foo::staticmethod();. Wenn der aktuelle Namespace currentnamespace ist, wird foo als currentnamespace\foo interpretiert. Wenn der Code, der foo verwendet, global ist und nicht in einem Namespace enthalten ist, wird foo als foo interpretiert. Warnung: Wenn eine Funktion oder eine Konstante im Namespace nicht definiert ist, wird der nicht eingeschränkte Funktionsname oder der Name der Konstante als globaler Funktionsname oder globaler Konstantenname interpretiert.

  • Bezeichner, oder Namen mit Präfix.Zum Beispiel $a = new subnamespace\foo(); oder subnamespace\foo::staticmethod();. Wenn der aktuelle Namespace currentnamespace ist, wird foo als currentnamespace\subnamespace\foo interpretiert. Wenn der Code, der foo verwendet, global ist und nicht in einem Namespace enthalten ist, wird foo als subnamespace\foo interpretiert.

  • Vollständiger Name oder Namen, die den Globalen Präfix-Operator enthalten.Zum Beispiel, $a = new \currentnamespace\foo(); oder \currentnamespace\foo::staticmethod();. In diesem Fall wird foo immer als der im Code verwendete Textname (literal name) currentnamespace\foo ge解析ert.

Nachfolgend ist ein Beispiel für die Verwendung dieser drei Methoden:

file1.php-Datei-Code

<?php
namespace Foo\Bar\subnamespace; 
const FOO = 1;
function foo() {}
class foo
{
    static function staticmethod() {}
}
?>

file2.php-Datei-Code

<?php
namespace Foo\Bar;
include 'file1.php';
const FOO = 2;
function foo() {}
class foo
{
    static function staticmethod() {}
}
/* Nichtqualifizierter Name */
foo(); // wird in die Funktion Foo\Bar\foo ge解析ert
foo::staticmethod(); // wird in die Klasse Foo\Bar\foo ,Methode staticmethod ge解析ert
echo FOO; // wird in die Konstante Foo\Bar\FOO ge解析ert
/* Bezeichner */
subnamespace\foo(); // wird in die Funktion Foo\Bar\subnamespace\foo ge解析ert
subnamespace\foo::staticmethod(); // wird in die Klasse Foo\Bar\subnamespace\foo, ge解析ert
                                  // sowie in die Methoden der Klasse staticmethod
echo subnamespace\FOO; // wird in die Konstante Foo\Bar\subnamespace\FOO ge解析ert
                                  
/* Vollständiger Name */
\Foo\Bar\foo(); // wird in die Funktion Foo\Bar\foo ge解析ert
\Foo\Bar\foo::staticmethod(); // wird in die Klasse Foo\Bar\foo, sowie in die Methoden der Klasse ge解析ert staticmethod
echo \Foo\Bar\FOO; // wird in die Konstante Foo\Bar\FOO ge解析ert
?>

Beachten Sie, dass der Zugriff auf beliebige globale Klassen, Funktionen oder Konstanten mit dem vollständigen Namen erfolgen kann, z.B. \strlen() oder \Exception oder \INI_ALL.

Zugriff auf globale Klassen, Funktionen und Konstanten innerhalb des Namensraums:

<?php
namespace Foo;
function strlen() {}
const INI_ALL = ; 3;
class Exception {}
$a = \strlen('hi'); // Aufruf der globalen Funktion strlen
$b = \INI_ALL; // Zugriff auf die globale Konstante INI_ALL
$c = new \Exception('error'); // Beispielhafter Aufruf der globalen Klasse Exception
?>

Namensräume und dynamische Spracheigenschaften

Die Implementierung von PHP-Namensräumen wird durch die dynamischen Eigenschaften der Sprache selbst beeinflusst. Daher muss, wenn der folgende Code in einen Namensraum überführt wird, auf dynamische Elemente zugegriffen werden.

example1.php Datei-Code:

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

Es muss der vollständige Name verwendet werden (einschließlich des Namensraums vor dem Klassennamen). Beachten Sie, dass der führende Backslash in dynamischen Klassennamen, Funktionsnamen oder Konstantennamen nicht erforderlich ist, da es zwischen dem eingeschränkten und dem vollständigen Namen keinen Unterschied gibt.

Dynamischer Zugriff auf die Elemente des Namensraums

<?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; // Ausgabe classname::__construct
$b = 'funcname';
$b(); // Ausgabe des Funktionsnamens
echo constant('constname'), '\n'; // Ausgabe global
/* Verwenden Sie Anführungszeichen, um den folgenden Stil zu verwenden: \\\'namespacename\\classname\\'*/
$a = '\namespacename\classname';
$obj = new $a; // Ausgabe namespacename\classname::__construct
$a = 'namespacename\classname';
$obj = new $a; // Ausgabe namespacename\classname::__construct
$b = 'namespacename\funcname';
$b(); // output namespacename\funcname
$b = 'namespacename\funcname';
$b(); // output namespacename\funcname
echo constant('\namespacename\constname'), '\n'; // output namespaced
echo constant('namespacename\constname'), '\n'; // output namespaced
?>

namespace keyword and __NAMESPACE__ constant

PHP supports two methods for abstractly accessing elements within the current namespace, the __NAMESPACE__ magic constant and the namespace keyword.

The value of the constant __NAMESPACE__ is a string containing the name of the current namespace. In global code, which is not included in any namespace, it contains an empty string.

__NAMESPACE__ example, code within a namespace

<?php
namespace MyProject;
echo '"', __NAMESPACE__, '"'; // output "MyProject"
?>

__NAMESPACE__ example, global code

<?php
echo '"', __NAMESPACE__, '"'; // output ""
?>

The constant __NAMESPACE__ is very useful when dynamically creating names, for example:

Using __NAMESPACE__ to dynamically create names

<?php
namespace MyProject;
function get($classname)
{
    $a = __NAMESPACE__ . '\\' . $classname;
    return new $a;
}
?>

The keyword namespace can be used to explicitly access elements in the current namespace or subnamespace. It is equivalent to the self operator within a class.

namespace operator, code within a namespace

<?php
namespace MyProject;
use blah\blah as mine; // see "Using namespaces: importing/aliasing"
blah\mine(); // calls function blah\blah\mine()
namespace\blah\mine(); // calls function MyProject\blah\mine()
namespace\func(); // calls function MyProject\func()
namespace\sub\func(); // calls function MyProject\sub\func()
namespace\cname::method(); // calls static method "method" of class MyProject\cname
$a = new namespace\sub\cname(); // instantiates object of class MyProject\sub\cname
$b = namespace\CONSTANT; // zuweist den Wert der Konstante MyProject\CONSTANT zu $b
?>

Namespace-Operator, globaler Code

<?php
namespace\func(); // ruft die Funktion func() auf
namespace\sub\func(); // ruft die Funktion sub\func() auf
namespace\cname::method(); // ruft die statische Methode "method" der Klasse cname auf
$a = new namespace\sub\cname(); // instanziert ein Objekt der Klasse sub\cname
$b = namespace\CONSTANT; // zuweist den Wert der Konstante CONSTANT zu $b
?>

Verwendung von Namespace: Alias/Import

PHP unterstützt zwei Arten der Verwendung von Aliases oder Importen: das Benennen von Klassennamen oder Namensräumen als Alias.

In PHP wird das Alias durch den Operator use realisiert. Hier ist ein Beispiel für alle drei möglichen Arten von Importen:

1、 Verwendung des use-Operators zum Import/Verwendung von Aliases

<?php
namespace foo;
use My\Full\Classname as Another;
// Der folgende Beispiel ist gleichwertig mit "use My\Full\NSname as NSname"
use My\Full\NSname;
// Import einer globalen Klasse
use \ArrayObject;
$obj = new namespace\Another; // Demonstration eines "foo\Another"-Objekts
$obj = new Another; // Demonstration eines Objekts von "My\Full\Classname"
NSname\subns\func(); // Aufruf der Funktion "My\Full\NSname\subns\func"
$a = new ArrayObject(array(1)); // Demonstration eines "ArrayObject"-Objekts
// Ohne "use \ArrayObject" zu verwenden, wird ein Objekt "foo\ArrayObject" demonstriert
?>

2、 mehrerer use-Anweisungen in einer Zeile

<?php
use My\Full\Classname as Another, My\Full\NSname;
$obj = new Another; // Demonstration eines Objekts von "My\Full\Classname"
NSname\subns\func(); // Aufruf der Funktion "My\Full\NSname\subns\func"
?>

Import-Operationen werden bei der Kompilierung ausgeführt, aber dynamische Klassennamen, Funktionsnamen oder Konstantennamen nicht.

3Import und dynamische Namen

<?php
use My\Full\Classname as Another, My\Full\NSname;
$obj = new Another; // Demonstration eines Objekts von "My\Full\Classname"
$a = 'Another';
$obj = new $a;      // Actualisierung eines Another-Objekts
?>

Darüber hinaus betrifft der Import nur nicht qualifizierte und qualifizierte Namen. Voll qualifizierte Namen sind bestimmt und daher nicht vom Import betroffen.

4、Import und voll qualifizierte Namen

<?php
use My\Full\Classname as Another, My\Full\NSname;
$obj = new Another; // Demonstration der Klasse My\Full\Classname
$obj = new \Another; // Demonstration der Klasse Another
$obj = new Another\thing; // Demonstration der Klasse My\Full\Classname\thing
$obj = new \Another\thing; // Demonstration der Klasse Another\thing
?>

Verwenden Sie den Namespace: Ersatzglobale Funktionen/Konstanten

In einem Namespace verwendet PHP eine andere Prioritätsstrategie, um einen nicht qualifizierten Klassennamen, eine Funktion oder eine Konstante zu解析. Der Klassename wird immer auf den Namen im aktuellen Namespace gelöst. Daher muss der voll qualifizierte Name verwendet werden, wenn auf Systeminterne oder nicht im Namespace enthaltenen Klassennamen zugegriffen wird, z.B.:

1、Zugriff auf globale Klassen im Namespace

<?php
namespace A\B\C;
class Exception extends \Exception {}
$a = new Exception('hi'); // $a ist ein Objekt der Klasse A\B\C\Exception
$b = new \Exception('hi'); // $b ist ein Objekt der Klasse Exception
$c = new ArrayObject; // Schwerer Fehler, die Klasse A\B\C\ArrayObject kann nicht gefunden werden
?>

Für Funktionen und Konstanten verwendet PHP, wenn die Funktion oder die Konstante im aktuellen Namespace nicht existiert, die Funktionen oder Konstanten im globalen Raum.

2、Ersatz globale Funktionen im Namespace/Konstanten

<?php
namespace A\B\C;
const E_ERROR = 45;
function strlen($str)
{
    return \strlen($str) - 1;
}
echo E_ERROR, "\n"; // Ausgabe ""45"
echo INI_ALL, "\n"; // Ausgabe ""7" - Verwenden Sie den globalen Konstanten INI_ALL
echo strlen('hi'), "\n"; // Ausgabe ""1"
if (is_array('hi')) { // Ausgabe "is not array"
    echo "is array\n";
} else {
    echo "is not 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. Prefixing the name with \ indicates that the name is in the global space, even if the name is located in another namespace.

Use global space specification

<?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 a class, 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();   // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法
            // 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"
            // 如果类 "B\D" 未找到,则尝试自动加载类 "B\D"
\B\foo();   // 调用命名空间 "B" 中的函数 "foo" 
\B::foo();  // 调用全局空间中的类 "B" 的 "foo" 方法
            // 如果类 "B" 未找到,则尝试自动加载类 "B"
// 当前命名空间中的静态方法或函数
A\B::foo();   // 调用命名空间 "A\A" 中定义的类 "B" 的 "foo" 方法
              // 如果类 "A\A\B" 未找到,则尝试自动加载类 "A\A\B"
\A\B::foo();  // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法
              // 如果类 "A\B" 未找到,则尝试自动加载类 "A\B"
?>

名称解析遵循下列规则:

  1. 对完全限定名称的函数,类和常量的调用在编译时解析。例如      new \A\B 解析为类 A\B

  2. 所有的非限定名称和限定名称(非完全限定名称)根据当前的导入规则在编译时进行转换。例如,如果命名空间     A\B\C 被导入为 C,那么对 C\D\e()     的调用就会被转换为 A\B\C\D\e()

  3. 在命名空间内部,所有的没有根据导入规则转换的限定名称均会在其前面加上当前的命名空间名称。例如,在命名空间     A\B 内部调用 C\D\e(),则 C\D\e()     会被转换为 A\B\C\D\e()

  4. 非限定类名根据当前的导入规则在编译时转换(用全名代替短的导入名称)。例如,如果命名空间     A\B\C 导入为C,则 new C()     被转换为 new A\B\C()

  5. 在命名空间内部(例如A\B),对非限定名称的函数调用是在运行时解析的。例如对函数      foo() 的调用是这样解析的:

    1. 在当前命名空间中查找名为 A\B\foo() 的函数

    2. 尝试查找并调用 全局(global) 空间中的函数 foo()

  6. 在命名空间(例如A\B)内部对非限定名称或限定名称类(非完全限定名称)的调用是在运行时解析的。下面是调用      new C()new D\E() 的解析过程:       new C()的解析: new D\E()的解析:为了引用全局命名空间中的全局类,必须使用完全限定名称 new \C()

    1. 在类名称前面加上当前命名空间名称变成:A\B\D\E,然后查找该类。

    2. 尝试自动加载类 A\B\D\E

    3. 在当前命名空间中查找A\B\C类。

    4. 尝试自动加载类A\B\C