Im Großen und Ganzen sind Namespaces eine Möglichkeit, Dinge zu kapseln. Dieses abstrakte Konzept findet sich vielerorts. Verzeichnisse werden beispielsweise in Betriebssystemen verwendet, um zusammengehörige Dateien zu gruppieren, und sie fungieren als Namespaces für die Dateien im Verzeichnis. Wenn dieses Prinzip auf den Bereich der Programmierung angewendet wird, handelt es sich um das Konzept des Namespace
In PHP werden Namespaces verwendet, um zwei Arten von Problemen zu lösen, die beim Erstellen von wiederverwendbarem Code wie Klassen oder Funktionen beim Schreiben von Klassenbibliotheken oder Anwendungen auftreten: Zum einen handelt es sich um vom Benutzer geschriebenen Code und um PHP-interne Klassen/Namenskonflikte zwischen Funktionen/Konstanten oder Klassen/Funktionen/Konstanten von Drittanbietern; eine andere Kategorie besteht darin, einen Aliasnamen (oder Kurznamen) für einen sehr langen Bezeichnernamen zu erstellen (normalerweise definiert, um die erste Kategorie von Problemen zu lindern), um die Lesbarkeit des Quellcodes zu verbessern. PHP-Namespaces bieten eine Möglichkeit, verwandte Klassen, Funktionen und Konstanten zu gruppieren. In diesem Artikel wird der PHP-Namespace im Detail vorgestellt
Obwohl jeder legale PHP-Code in einen Namespace aufgenommen werden kann, sind nur die folgenden Codetypen von dem Namespace betroffen: Klassen (einschließlich abstrakter Klassen und Merkmale), Schnittstellen, Funktionen und Konstanten
Ein Namespace wird mit dem Schlüsselwort namespace deklariert. Wenn eine Datei einen Namespace enthält, muss sie den Namespace vor allen anderen Codes außer einem deklarieren: Schlüsselwort deklarieren
<?<span style="color: #000000;">php namespace MyProject; </span><span style="color: #0000ff;">const</span> CONNECT_OK = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">class</span> Connection { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span><span style="color: #0000ff;">function</span> connect() { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span>?>
Subnamespace
Ähnlich wie die Beziehung zwischen Verzeichnissen und Dateien ermöglichen Ihnen PHP-Namespaces auch die Angabe hierarchischer Namespace-Namen. Daher können Namespace-Namen hierarchisch definiert werden
<?<span style="color: #000000;">php namespace MyProject\Sub\Level; </span><span style="color: #0000ff;">const</span> CONNECT_OK = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">class</span> Connection { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span><span style="color: #0000ff;">function</span> connect() { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span>?>
<?<span style="color: #000000;">php namespace MyProject\Sub\Level; </span><span style="color: #0000ff;">const</span> NUM = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">echo</span> NUM;<span style="color: #008000;">//</span><span style="color: #008000;">1</span> <span style="color: #0000ff;">echo</span> \MyProject\Sub\Level\NUM;<span style="color: #008000;">//</span><span style="color: #008000;">1</span> ?>
Mehrere Namespaces können in derselben Datei definiert werden. Es gibt zwei Syntaxformen zum Definieren mehrerer Namespaces in derselben Datei
In der tatsächlichen Programmierpraxis wird dringend davon abgeraten, mehrere Namespaces in derselben Datei zu definieren. Diese Methode wird hauptsächlich verwendet, um mehrere PHP-Skripte in derselben Datei zusammenzuführen
【1】Einfache Kombinationssyntax (nicht empfohlen)
<?<span style="color: #000000;">php namespace MyProject; </span><span style="color: #0000ff;">const</span> CONNECT_OK = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">class</span> Connection { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span><span style="color: #0000ff;">function</span> connect() { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } namespace AnotherProject; </span><span style="color: #0000ff;">const</span> CONNECT_OK = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">class</span> Connection { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span><span style="color: #0000ff;">function</span> connect() { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span>?>
【2】Syntax für geschweifte Klammern
<?<span style="color: #000000;">php namespace MyProject { </span><span style="color: #0000ff;">const</span> CONNECT_OK = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">class</span> Connection { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span><span style="color: #0000ff;">function</span> connect() { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } } namespace AnotherProject { </span><span style="color: #0000ff;">const</span> CONNECT_OK = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">class</span> Connection { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span><span style="color: #0000ff;">function</span> connect() { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } } </span>?>
<?<span style="color: #000000;">php namespace MyProject { </span><span style="color: #0000ff;">const</span> NUM = 1<span style="color: #000000;">; } namespace AnotherProject { </span><span style="color: #0000ff;">const</span> NUM = 2<span style="color: #000000;">; </span><span style="color: #0000ff;">echo</span> NUM;<span style="color: #008000;">//</span><span style="color: #008000;">2</span> <span style="color: #0000ff;">echo</span> \MyProject\NUM;<span style="color: #008000;">//</span><span style="color: #008000;">1</span> <span style="color: #000000;">} </span>?>
Global
Um globalen Nicht-Namespace-Code mit Namespace-Code zu kombinieren, kann nur die Syntax mit geschweiften Klammern verwendet werden. Globaler Code muss in geschweifte Klammern mit einer unbenannten Namespace-Anweisung
eingeschlossen werden<?<span style="color: #000000;">php namespace MyProject { </span><span style="color: #0000ff;">const</span> CONNECT_OK = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">class</span> Connection { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span><span style="color: #0000ff;">function</span> connect() { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } } namespace { </span><span style="color: #008000;">//</span><span style="color: #008000;"> global code</span> <span style="color: #008080;">session_start</span><span style="color: #000000;">(); </span><span style="color: #800080;">$a</span> =<span style="color: #000000;"> MyProject\connect(); </span><span style="color: #0000ff;">echo</span> MyProject\Connection::<span style="color: #000000;">start(); } </span>?>
Unqualifizierter Name bezieht sich auf einen Bezeichner, der kein Namespace-Trennzeichen im Namen enthält, z. B. Foo
Qualifizierter Name bezieht sich auf einen Bezeichner, der ein Namespace-Trennzeichen im Namen enthält, z. B. FooBar
Der vollständig qualifizierte Name bezieht sich auf einen Bezeichner, dessen Name ein Namespace-Trennzeichen enthält und mit einem Namespace-Trennzeichen beginnt, z. B. FooBar. namespaceFoo ist auch ein vollständig qualifizierter Name
Wenn Sie dynamisch auf ein Element zugreifen möchten (z. B. eine Variablenfunktion), müssen Sie den vollständig qualifizierten Namen
verwenden<?<span style="color: #000000;">php namespace MyProject; </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> test(){ </span><span style="color: #0000ff;">echo</span> '111'<span style="color: #000000;">; } </span><span style="color: #800080;">$var1</span> = 'test'<span style="color: #000000;">; </span><span style="color: #800080;">$var2</span> = '\MyProject\test'<span style="color: #000000;">; </span><span style="color: #800080;">$var1</span>();<span style="color: #008000;">//</span><span style="color: #008000;">报错</span> <span style="color: #800080;">$var2</span>();/111 ?>
PHP unterstützt zwei abstrakte Methoden für den Zugriff auf interne Elemente des aktuellen Namespace: die magische Konstante __NAMESPACE__ und das Namespace-Schlüsselwort
Der Wert der Konstante __NAMESPACE__ ist eine Zeichenfolge, die den Namen des aktuellen Namespace enthält. Im globalen Code, der in keinem Namespace enthalten ist, enthält er eine leere Zeichenfolge
<?<span style="color: #000000;">php namespace MyProject; </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> test(){ </span><span style="color: #0000ff;">echo</span> '111'<span style="color: #000000;">; } </span><span style="color: #800080;">$var</span> = __NAMESPACE__.'\test'<span style="color: #000000;">; </span><span style="color: #800080;">$var</span>();<span style="color: #008000;">//</span><span style="color: #008000;">111</span> ?>
Das Schlüsselwort „Namespace“ kann verwendet werden, um explizit auf Elemente im aktuellen Namespace oder in Unter-Namespaces zuzugreifen. Es entspricht dem self-Operator in der Klasse
<?<span style="color: #000000;">php namespace MyProject; </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> test(){ </span><span style="color: #0000ff;">echo</span> '111'<span style="color: #000000;">; } test();</span><span style="color: #008000;">//</span><span style="color: #008000;">111</span> __NAMESPACE__.test();<span style="color: #008000;">//</span><span style="color: #008000;">111</span> namespace\test();<span style="color: #008000;">//</span><span style="color: #008000;">111</span> ?>
Wenn kein Namespace definiert ist, werden alle Klassen und Funktionen im globalen Raum definiert, genau wie vor der Einführung des Namespace-Konzepts durch PHP. Das Präfix des Namens zeigt an, dass sich der Name im globalen Raum befindet, auch wenn der Name in einem anderen Namensraum liegt
<?<span style="color: #000000;">php namespace A\B\C; </span><span style="color: #008000;">/*</span><span style="color: #008000;"> 这个函数是 A\B\C\fopen </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">function</span> <span style="color: #008080;">fopen</span><span style="color: #000000;">() { </span><span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span> <span style="color: #800080;">$f</span> = \<span style="color: #008080;">fopen</span>(...); <span style="color: #008000;">//</span><span style="color: #008000;"> 调用全局的fopen函数</span> <span style="color: #0000ff;">return</span> <span style="color: #800080;">$f</span><span style="color: #000000;">; } </span>?>
php允许通过别名引用或导入外部的完全限定名称,是命名空间的一个重要特征。这有点类似于在类unix文件系统中可以创建对其它的文件或目录的符号连接
所有支持命名空间的PHP版本支持三种别名或导入方式:为类名称使用别名、为接口使用别名或为命名空间名称使用别名
在PHP中,别名是通过操作符 use 来实现的
别名
<?<span style="color: #000000;">php namespace hello\world\test; </span><span style="color: #0000ff;">use</span> hello\world\test <span style="color: #0000ff;">as</span> t;<span style="color: #008000;">//</span><span style="color: #008000;">用t来替代hello\world\test</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> demo(){ </span><span style="color: #0000ff;">echo</span> '111'<span style="color: #000000;">; } t\demo();</span><span style="color: #008000;">//</span><span style="color: #008000;">111</span> ?>
as可以省略
<?<span style="color: #000000;">php namespace hello\world\test; </span><span style="color: #0000ff;">use</span> hello\world\test;<span style="color: #008000;">//</span><span style="color: #008000;">用test来替代hello\world\test</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> demo(){ </span><span style="color: #0000ff;">echo</span> '111'<span style="color: #000000;">; } test\demo();</span><span style="color: #008000;">//</span><span style="color: #008000;">111</span> ?>
导入
<?<span style="color: #000000;">php </span><span style="color: #0000ff;">use</span><span style="color: #000000;"> \ArrayObject; </span><span style="color: #800080;">$a</span> = <span style="color: #0000ff;">new</span> ArrayObject([]);<span style="color: #008000;">//</span><span style="color: #008000;">若不使用"use \ArrayObject" ,则实例化一个 foo\ArrayObject 对象</span> ?>
为了简化,一行中可以包含多个use语句
<?<span style="color: #000000;">php </span><span style="color: #0000ff;">use</span> My\Full\Classname <span style="color: #0000ff;">as</span> Another,<span style="color: #000000;"> My\Full\NSname; </span><span style="color: #800080;">$obj</span> = <span style="color: #0000ff;">new</span> Another; <span style="color: #008000;">//</span><span style="color: #008000;"> 实例化 My\Full\Classname 对象</span> NSname\subns\func(); <span style="color: #008000;">//</span><span style="color: #008000;"> 调用函数 My\Full\NSname\subns\func</span> ?>