Was ist ein Namensraum? Detaillierte Erklärung der Namespaces in PHP

怪我咯
Freigeben: 2023-03-09 21:28:01
nach vorne
5996 Leute haben es durchsucht

Was ist ein Namespace? Dieser Artikel wird Ihnen ein tiefgreifendes Verständnis der Namespaces in PHP vermitteln. Ich hoffe, er wird Ihnen hilfreich sein.

Was ist ein Namensraum? Detaillierte Erklärung der Namespaces in PHP

Was ist ein Namespace?

Im weitesten Sinne ist Namespace eine Möglichkeit, Dinge zu kapseln, und dieses abstrakte Konzept ist an vielen Stellen zu sehen. Beispielsweise werden Verzeichnisse in Betriebssystemen verwendet, um zusammengehörige Dateien zu gruppieren, und sie fungieren als Namespaces für die Dateien im Verzeichnis.

Ein einfaches Beispiel: Die Datei foo.txt kann gleichzeitig in den Verzeichnissen /home/greg und /home/other vorhanden sein, aber zwei foo.txt-Dateien können nicht im selben Verzeichnis vorhanden sein. Außerdem müssen wir beim Zugriff auf die foo.txt-Datei außerhalb des Verzeichnisses /home/greg den Verzeichnisnamen und das Verzeichnistrennzeichen vor den Dateinamen setzen, zum Beispiel /home/greg/foo.txt. Die Anwendung dieses Prinzips auf den Bereich der Programmierung ist das Konzept des Namespace.

Definition des Namespace

Namespace in PHP wurde in PHP5.3 hinzugefügt. Wenn Sie C++ kennen, dann sind Namespaces nichts Neues. Allerdings sind Namespaces in PHP immer noch sehr wichtig.

PHP-Namespace kann die folgenden zwei Arten von Problemen lösen:

  • Von Benutzern geschriebener Code und interne Klassen/Funktionen/Konstanten von PHP oder Klassen/Funktionen/Konstanten von Drittanbietern Namenskonflikte zwischen

  • Erstellen Sie einen Aliasnamen (oder Kurznamen) für einen sehr langen Bezeichnernamen (normalerweise definiert, um die erste Art von Problem zu lindern), um die Lesbarkeit des Quellcodes zu verbessern.

1) Definieren Sie einen Namespace (unter Verwendung des Schlüsselworts namespace)

Obwohl jeder legale PHP-Code in einen Namespace eingeschlossen werden kann, sind nur Klassen ( (einschließlich abstrakter Klassen und Merkmale), Schnittstellen, Funktionen und Konstanten werden von Namespaces beeinflusst.

Die Definition eines Namespace muss über das Schlüsselwort namespace deklariert werden. Das Syntaxformat lautet wie folgt:

namespace 命名空间名;
Nach dem Login kopieren

[Beispiel] Lassen Sie uns demonstrieren, wie ein Namespace definiert wird:

<?php
    namespace MyProject;    // 定义名为 MyProject 的命名空间。
    const CONNECT_OK = 1;
    class Myclass {
        /* ... */
    }
    function Myfunc() {
        /* ... */
    }
?>
Nach dem Login kopieren

Vor der Deklaration des Namespace darf mit Ausnahme der Declare-Anweisung, die zum Definieren der Codierungsmethode der Quelldatei verwendet wird, kein Nicht-PHP-Code (einschließlich Leerzeichen) vor der Namespace-Deklaration angezeigt werden.

Darüber hinaus kann im Gegensatz zu anderen Sprachfunktionen von PHP derselbe Namespace in mehreren Dateien definiert werden, wodurch der Inhalt desselben Namespace aufgeteilt und in verschiedenen Dateien gespeichert werden kann.

2) Sub-Namespaces definieren

ist den Verzeichnissen und Dateien sehr ähnlich. Namespaces in PHP ermöglichen auch die Angabe hierarchischer Namespace-Namen. Daher kann der Name des Namespace hierarchisch definiert werden:

namespace App\Model;
namespace App\Controller\Home;
Nach dem Login kopieren

[Beispiel] Definieren Sie einen Unternamespace:

<?php
    namespace MyProject\Controller\Home;    // 定义名为 MyProject 的命名空间。
    const CONNECT_OK = 1;
    class Myclass {
        /* ... */
    }
    function Myfunc() {
        /* ... */
    }
?>
Nach dem Login kopieren

3) Im selben Datei Definieren Sie mehrere Namespaces in

Sie können auch mehrere Namespaces in einer Datei definieren. Es gibt zwei Syntaxformen zum Definieren mehrerer Namespaces in derselben Datei. Das Folgende ist ein Beispiel zur Veranschaulichung:

[Beispiel] Definieren Sie mehrere Namespaces – einfache Kombinationssyntax.

<?php
    namespace MyProject;
    const CONNECT_OK = 1;
    class className {
        /* ... */
    }
    namespace AnotherProject;
    const CONNECT_OK = 1;
    class className {
        /* ... */
    }
?>
Nach dem Login kopieren

[Beispiel] Definieren Sie mehrere Namespaces – Klammer { }-Syntax.

<?php
    namespace MyProject{
        const CONNECT_OK = 1;
        class className {
            /* ... */
        }
    }
    namespace AnotherProject{
        const CONNECT_OK = 1;
        class className {
            /* ... */
        }
    }
?>
Nach dem Login kopieren

In der tatsächlichen Programmierpraxis wird nicht empfohlen, mehrere Namespaces in derselben Datei zu definieren. Die Definition mehrerer Namespaces wird hauptsächlich verwendet, um mehrere PHP-Skripte in derselben Datei zu kombinieren. Es wird empfohlen, beim Definieren mehrerer Namespaces die Syntax mit geschweiften Klammern zu verwenden.

Um den Code im globalen Nicht-Namespace mit dem Code im Namespace zu kombinieren, können Sie die Syntax nur in geschweiften Klammern verwenden. Gleichzeitig muss der globale Code eine unbenannte Namespace-Anweisung plus verwenden in geschweiften Klammern wie folgt:

<?php
    namespace MyProject{        // 命名空间中的代码
        const CONNECT_OK = 1;
        class className {
            /* ... */
        }
    }
    namespace {                 // 命名空间外的全局代码
        $obj = new MyProject\className();
    }
?>
Nach dem Login kopieren

Verwendung von Namespaces: Grundlagen

Bevor Sie die Verwendung von Namespaces besprechen, müssen Sie PHP How verstehen um zu wissen, welches Namespace-Element verwendet werden soll. Wir können eine einfache Analogie zwischen dem PHP-Namespace und dem Dateisystem ziehen. Es gibt drei Möglichkeiten, auf eine Datei im Dateisystem zuzugreifen:

  • Relatives Dateinamenformat wie foo.txt. Es wird als currentdirectory/foo.txt geparst, wobei currentdirectory das aktuelle Verzeichnis darstellt. Wenn das aktuelle Verzeichnis also /home/foo ist, wird der Dateiname als /home/foo/foo.txt geparst;

  • Das Format des relativen Pfadnamens ist beispielsweise Unterverzeichnis/foo .txt. Es wird als aktuelles Verzeichnis/Unterverzeichnis/foo.txt analysiert.

  • Das absolute Pfadnamenformat ist etwa /main/foo.txt. Es wird als /main/foo.txt geparst.

Elemente im PHP-Namespace verwenden das gleiche Prinzip. Beispielsweise kann auf einen Klassennamen unter einem Namespace auf drei Arten verwiesen werden:

  • ein nicht qualifizierter Name oder ein Klassenname, der kein Präfix enthält, wie z. B. $a=new foo(); oder foo::staticmethod();. Wenn der aktuelle Namespace currentnamespace ist, wird foo in currentnamespacefoo aufgelöst. Wenn der Code, der foo verwendet, global ist und keinen Code in einem Namespace enthält, wird foo als foo aufgelöst.

  • 限定名称,或包含前缀的名称,例如$a = new subnamespace\foo();subnamespace\foo::staticmethod();。如果当前的命名空间是 currentnamespace,则 foo 会被解析为 currentnamespace\subnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为 subnamespace\foo。

  • 完全限定名称,或包含了全局前缀操作符的名称,例如$a = new \currentnamespace\foo();\currentnamespace\foo::staticmethod();。在这种情况下,foo 总是被解析为代码中的文字名 currentnamespace\foo。

警告:如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。

下面是一个使用这三种方式的实例,我们需要两个 PHP 源文件,分别是 demo.php 和 index.php,示例代码如下:

1) demo.php

<?php
    namespace Foo\Bar\Demo;
    const FOO = 1;
    function foo() {}
    class foo
    {
        public function demo() {
            echo &#39;命名空间为:Foo\Bar\Demo&#39;;
        }
    }
?>
Nach dem Login kopieren

2) index.php

<?php
    namespace Foo\Bar;
    include &#39;Demo.php&#39;;
    const FOO = 2;
    function foo() {
        echo &#39;Foo\Bar 命名空间下的 foo 函数<br>&#39;;
    }
    class foo
    {
        static function demo(){
            echo &#39;命名空间为:Foo\Bar<br>&#39;;
        }
    }
    /* 非限定名称 */
    foo();                  // 解析为 Foo\Bar\foo resolves to function Foo\Bar\foo
    foo::demo();            // 解析为类 Foo\Bar\foo 的静态方法 staticmethod。
    echo FOO.&#39;<br>&#39;;        // 解析为常量 Foo\Bar\FOO
    /* 限定名称 */
    Demo\foo();             // 解析为函数 Foo\Bar\Demo\foo
    Demo\foo::demo();       // 解析为类 Foo\Bar\Demo\foo,
                            // 以及类的方法 demo
    echo Demo\FOO.&#39;<br>&#39;;   // 解析为常量 Foo\Bar\Demo\FOO
                                     
    /* 完全限定名称 */
    \Foo\Bar\foo();         // 解析为函数 Foo\Bar\foo
    \Foo\Bar\foo::demo();   // 解析为类 Foo\Bar\foo, 以及类的方法 demo
    echo \Foo\Bar\FOO.&#39;<br>&#39;; // 解析为常量 Foo\Bar\FOO
?>
Nach dem Login kopieren

运行结果如下:

Foo\Bar 命名空间下的 foo 函数
命名空间为:Foo\Bar
2
Foo\Bar\Demo 命名空间下的 foo 函数
命名空间为:Foo\Bar\Demo
1
Foo\Bar 命名空间下的 foo 函数
命名空间为:Foo\Bar
2
Nach dem Login kopieren

注意:访问任意全局类、函数或常量,都可以使用完全限定名称,例如 \strlen() 或 \Exception 等。

使用命名空间:别名/导入

PHP 允许通过别名引用或导入的方式来使用外部的命名空间,这是命名空间的一个重要特征。这有点类似于在类 unix 文件系统中可以创建对其它的文件或目录的符号连接。

使用 use 关键字可以实现命名空间的导入,从 PHP5.6 开始允许导入函数和常量,并为它们设置别名。语法格式如下:

use namespace;
Nach dem Login kopieren

在 PHP 中,别名是通过操作符 use 与 as 来实现的,语法格式如下:

use 命名空间 as 别名;
Nach dem Login kopieren

【示例】使用 use 操作符导入和使用别名。

<?php
    namespace foo;
    use My\Full\Classname as Another;
    // 下面的例子与 use My\Full\NSname as NSname 相同
    use My\Full\NSname;
    // 导入一个全局类
    use ArrayObject;
    // 导入一个函数
    use function My\Full\functionName;
    // 导入一个函数并定义别名
    use function My\Full\functionName as func;
    // 导入一个常量
    use const My\Full\CONSTANT;
    $obj = new namespace\Another;   // 实例化 foo\Another 对象
    $obj = new Another;             // 实例化 My\Full\Classname 对象
    NSname\subns\func();            // 调用 My\Full\NSname\subns\func 函数
    $a = new ArrayObject(array(1)); // 实例化 ArrayObject 对象
                                    // 如果不使用 "use \ArrayObject" ,则实例化一个 foo\ArrayObject 对象
    func();                         // 调用 My\Full\functionName 函数
    echo CONSTANT;                  // 打印 My\Full\CONSTANT 常量
?>
Nach dem Login kopieren

注意:对命名空间中的名称(包含命名空间分隔符的完全限定名称,如 Foo\Bar ,以及相对的不包含命名空间分隔符的全局名称,如 FooBar)来说,前导的反斜杠是不必要的也是不推荐的,因为导入的名称必须是完全限定的,不会根据当前的命名空间作相对解析。

为了简化操作,PHP 还支持在一行中导入多个命名空间,中间使用,隔开,示例代码如下:

<?php
    use My\Full\Classname as Another, My\Full\NSname;
    $obj = new Another;     // 实例化 My\Full\Classname 对象
    NSname\subns\func();    // 调用 My\Full\NSname\subns\func 函数
?>
Nach dem Login kopieren

导入操作是编译执行的,但动态的类名称、函数名称或常量名称则不是。

<?php
    use My\Full\Classname as Another, My\Full\NSname;
    $obj = new Another; // 实例化一个 My\Full\Classname 对象
    $a = &#39;Another&#39;;
    $obj = new $a;      // 实际化一个 Another 对象
?>
Nach dem Login kopieren

另外,导入操作只影响非限定名称和限定名称。完全限定名称由于是确定的,故不受导入的影响。

namespace 关键字和 __NAMESPACE__ 常量

PHP 支持两种抽象的访问当前命名空间内部元素的方法,__NAMESPACE__ 魔术常量和 namespace 关键字。

__NAMESPACE__ 常量的值是包含当前命名空间名称的字符串。在全局的,不包括在任何命名空间中的代码,它是一个空的字符串。示例代码如下:

<?php
    namespace App\Controller\Home;
    echo __NAMESPACE__;
?>
Nach dem Login kopieren

运行结果如下:

App\Controller\Home
Nach dem Login kopieren

namespace 关键字可用来显式访问当前命名空间或子命名空间中的元素,它等价于类中的 self 操作符。示例代码如下:

<?php
    namespace MyProject;
    use Foo\Bar\Demo as demo;       // 导入 Foo\Bar\Demo 命名空间
    blah\mine();                    // 调用 MyProject\blah\mine() 函数
    namespace\blah\mine();          // 调用 MyProject\blah\mine() 函数
    namespace\func();               // 调用 MyProject\func() 函数
    namespace\sub\func();           // 调用 MyProject\sub\func() 函数
    namespace\cname::method();      // 调用 MyProject\cname 类的静态方法 method
    $a = new namespace\sub\cname(); // 实例化 MyProject\sub\cname 对象
    $b = namespace\CONSTANT;        // 将常量 MyProject\CONSTANT 的值赋给 $b
?>
Nach dem Login kopieren

命名空间名称解析规则

在说明名称解析规则之前,我们先来看看命名空间名称的定义:

  • 非限定名称:名称中不包含命名空间分隔符的标识符,例如 Foo;

  • 限定名称:名称中含有命名空间分隔符的标识符,例如 Foo\Bar;

  • 完全限定名称:名称中包含命名空间分隔符,并以命名空间分隔符开始的标识符,例如 \Foo\Bar。namespace\Foo 也是一个完全限定名称。

名称解析遵循下列规则:

  • Aufrufe an vollständig qualifizierte Namen von Funktionen, Klassen und Konstanten werden zur Kompilierungszeit aufgelöst. Beispielsweise wird neues AB in die Klasse AB aufgelöst.
  • Alle unqualifizierten Namen und qualifizierten Namen (nicht vollständig qualifizierte Namen) werden zur Kompilierungszeit gemäß den aktuellen Importregeln konvertiert. Wenn beispielsweise der Namespace ABC als C importiert wird, werden Aufrufe von CDe() in ABCDe() konvertiert.
  • Innerhalb des Namespace werden alle qualifizierten Namen, die nicht gemäß den Importregeln konvertiert werden, vorangestellt es mit dem aktuellen Namespace-Namen. Wenn beispielsweise CDe() innerhalb des Namensraums AB aufgerufen wird, wird CDe() in ABCDe() konvertiert.
  • nicht qualifizierte Klassennamen werden zur Kompilierzeit gemäß den aktuellen Importregeln konvertiert (stattdessen werden vollständige Namen verwendet). des kurzen Importnamens). Wenn beispielsweise der Namespace ABC als C importiert wird, wird new C() in new ABC() konvertiert.
  • Innerhalb eines Namespace (z. B. AB) werden Funktionsaufrufe zu unqualifizierten Namen zur Laufzeit aufgelöst. Ein Aufruf der Funktion foo() wird beispielsweise wie folgt analysiert:
    • Suchen Sie nach einer Funktion namens ABfoo() im aktuellen Namespace

    • Versuchen Sie es Finden und rufen Sie die Funktion foo() im globalen Raum auf.

  • Aufrufe an unqualifizierte Namen oder qualifizierte Namensklassen (nicht vollständig qualifizierte Namen) innerhalb eines Namensraums (z. B. AB) werden zur Laufzeit aufgelöst. Das Folgende ist der Parsing-Prozess zum Aufrufen von new C() und new DE():
    • Parsing von new C():

      • Suchen Sie die ABC-Klasse in der aktuellen namespace;
      • Versuchen Sie, die Klasse ABC automatisch zu laden.
    • Parsing von neuem DE():

      • Fügen Sie den aktuellen Namespace-Namen vor dem Klassennamen hinzu, um ABDE zu erhalten, und suchen Sie dann für die Klasse ;
      • Versuchen Sie, die Klasse ABDE automatisch zu laden.
    • Um auf eine globale Klasse im globalen Namensraum zu verweisen, muss der vollqualifizierte Name new C() verwendet werden.

Empfohlenes Lernen: „PHP-Video-Tutorial

Das obige ist der detaillierte Inhalt vonWas ist ein Namensraum? Detaillierte Erklärung der Namespaces in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:biancheng.net
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!