Heim > Backend-Entwicklung > PHP-Tutorial > Vollständige Beherrschung von PHP-Namespaces

Vollständige Beherrschung von PHP-Namespaces

小云云
Freigeben: 2023-03-20 20:20:01
Original
1547 Leute haben es durchsucht

Namespace wird verwendet, um Namenskonflikte zwischen vom Benutzer geschriebenem Code und PHP-internen Klassen/Funktionen/Konstanten oder Klassen/Funktionen/Konstanten von Drittanbietern zu lösen. Erstellen Sie einen Aliasnamen (oder Kurznamen) für einen sehr langen Bezeichnernamen, um die Lesbarkeit des Quellcodes zu verbessern.

Obwohl jeder legale PHP-Code in einen Namespace eingebunden werden kann, sind nur die folgenden Codetypen von dem Namespace betroffen: Klassen (einschließlich abstrakter Klassen und Merkmale), Schnittstellen, Funktionen und Konstanten.

Wenn eine Datei einen Namespace enthält, muss sie den Namespace vor allen anderen Codes außer einem deklarieren: declare-Schlüsselwort, das zum Definieren der Quelldateikodierung declare-Anweisung verwendet wird. Code, einschließlich Leerzeichen, darf nicht vor einer Namespace-Deklaration stehen.

Im Gegensatz zu anderen PHP-Sprachfunktionen kann derselbe Namespace in mehreren Dateien definiert werden, wodurch der Inhalt desselben Namespace aufgeteilt und in verschiedenen Dateien gespeichert werden kann.

Unternamespaces definieren

<?phpnamespace MyProject\Sub\Level;const CONNECT_OK = 1;class Connection { /* ... */ }function connect() {/* ... */ }
Nach dem Login kopieren

Mehrere Namespaces in derselben Datei definieren

<?phpnamespace MyProject;const CONNECT_OK = 1;class Connection { /* ... */ }function connect() { /* ... */  }namespace AnotherProject;const CONNECT_OK = 1;class Connection { /* ... */ }function connect() { /* ... */  }
Nach dem Login kopieren

Es wird nicht empfohlen, diese Syntax zu verwenden, um mehrere Namespaces in einem einzigen zu definieren Dateinamensraum. Es wird empfohlen, die folgende Syntax in geschweiften Klammern zu verwenden.

<?phpnamespace MyProject {const CONNECT_OK = 1;class Connection { /* ... */ }function connect() { /* ... */  }
}namespace AnotherProject {const CONNECT_OK = 1;class Connection { /* ... */ }function connect() { /* ... */  }
}
Nach dem Login kopieren

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 zu kombinieren.

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.

Klassen können auf drei Arten referenziert werden:

  1. Ein unqualifizierter Name, oder ein Klassenname ohne Präfix, wie zum Beispiel $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 geparst. Warnung: Wenn eine Funktion oder Konstante im Namespace undefiniert ist, wird der unqualifizierte Funktions- oder Konstantenname in einen globalen Funktions- oder Konstantennamen aufgelöst.

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

  3. Ein vollständig qualifizierter Name oder ein Name, der einen globalen Präfixoperator enthält, zum Beispiel $a = new currentnamespacefoo(); oder currentnamespacefoo: :staticmethod ();. In diesem Fall wird foo im Code immer in den Literalnamen currentnamespacefoo aufgelöst.

Beachten Sie, dass Sie für den Zugriff auf globale Klassen, Funktionen oder Konstanten einen vollständig qualifizierten Namen verwenden können, z. B. strlen() oder Exception oder INI_ALL.

Hinweis: Der relative Pfad der Datei, die in der untergeordneten Datei der übergeordneten Datei enthalten ist, gilt für das übergeordnete Dateiverzeichnis, nicht für das untergeordnete Dateiverzeichnis.

PHP unterstützt zwei abstrakte Methoden für den Zugriff auf Elemente innerhalb des aktuellen Namespace: __NAMESPACE__magische Konstanten und das Schlüsselwort namespace.

__NAMESPACE__ kann eine Zeichenfolge darstellen, die anderen sind mit Namespace identisch.

Verwenden Sie den Use-Operator, um Aliase zu importieren/verwenden

<?phpnamespace foo;use My\Full\Classname as Another;// 下面的例子与 use My\Full\NSname as NSname 相同use My\Full\NSname;// 导入一个全局类use ArrayObject;// importing a function (PHP 5.6+)use function My\Full\functionName;// aliasing a function (PHP 5.6+)use function My\Full\functionName as func;// importing a constant (PHP 5.6+)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(); // calls function My\Full\functionNameecho CONSTANT; // echoes the value of My\Full
Nach dem Login kopieren

Importieren/verwenden Sie Aliase über den Use-Operator, einschließlich mehrerer Use-Anweisungen in einer Zeile

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

Import und dynamische Namen

Der Importvorgang wird während der Kompilierung ausgeführt, der dynamische Klassenname, Funktionsname oder Konstantenname jedoch schon nicht .

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

Importieren und vollständig qualifizierte Namen

Importvorgänge wirken sich nur auf unqualifizierte und qualifizierte Namen aus. Vollqualifizierte Namen sind von Importen nicht betroffen, da sie deterministisch sind.

<?phpuse My\Full\Classname as Another, My\Full\NSname;$obj = new Another; // instantiates object of class My\Full\Classname$obj = new \Another; // instantiates object of class Another$obj = new Another\thing; // instantiates object of class My\Full\Classname\thing$obj = new \Another\thing; // instantiates object of class Another\thing
Nach dem Login kopieren

Globale Leerzeichenanweisungen verwenden

<?phpnamespace A\B\C;/* 这个函数是 A\B\C\fopen */function fopen() { 
     /* ... */
     $f = \fopen(...); // 调用全局的fopen函数
     return $f;
}
Nach dem Login kopieren

Wenn PHP in einem Namespace auf einen nicht qualifizierten Klassen-, Funktions- oder Konstantennamen trifft, verwendet es eine andere Prioritätsstrategie, um den Namen aufzulösen. Klassennamen werden immer in Namen im aktuellen Namespace aufgelöst. Daher müssen Sie beim Zugriff auf einen Klassennamen, der systemintern oder nicht in einem Namespace enthalten ist, den vollständig qualifizierten Namen verwenden. Wenn bei Funktionen und Konstanten die Funktion oder Konstante nicht im aktuellen Namensraum vorhanden ist, greift PHP auf die Verwendung der Funktion oder Konstante im globalen Raum zurück.

<?phpnamespace A\B\C;class Exception extends \Exception {}$a = new Exception(&#39;hi&#39;); // $a 是类 A\B\C\Exception 的一个对象$b = new \Exception(&#39;hi&#39;); // $b 是类 Exception 的一个对象$c = new ArrayObject; // 致命错误, 找不到 A\B\C\ArrayObject 类
Nach dem Login kopieren
<?phpnamespace A\B\C;const E_ERROR = 45;function strlen($str){
    return \strlen($str) - 1;
}echo E_ERROR, "\n"; // 输出 "45"echo INI_ALL, "\n"; // 输出 "7" - 使用全局常量 INI_ALLecho strlen(&#39;hi&#39;), "\n"; // 输出 "1"if (is_array(&#39;hi&#39;)) { // 输出 "is not array"
    echo "is array\n";
} else {    echo "is not array\n";
}
Nach dem Login kopieren

Die Namensauflösung folgt den folgenden Regeln:

  1. Aufrufe von Funktionen, Klassen und Konstanten mit vollständig qualifizierten Namen werden zur Kompilierungszeit aufgelöst. Beispielsweise wird „Neu AB“ in die Klasse „AB“ aufgelöst.

  2. Alle unqualifizierten Namen und qualifizierten Namen (nicht vollständig qualifizierte Namen) werden zur Kompilierzeit gemäß den aktuellen Importregeln konvertiert. Wenn beispielsweise der Namespace ABC als C importiert wird, werden Aufrufe von CDe() in ABCDe() konvertiert.

  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。

<?phpnamespace A;use B\D, C\E as F;// 函数调用foo();      // 首先尝试调用定义在命名空间"A"中的函数foo()
            // 再尝试调用全局函数 "foo"\foo();     // 调用全局空间函数 "foo" my\foo();   // 调用定义在命名空间"A\my"中函数 "foo" F();        // 首先尝试调用定义在命名空间"A"中的函数 "F" 
            // 再尝试调用全局函数 "F"// 类引用new B();    // 创建命名空间 "A" 中定义的类 "B" 的一个对象
            // 如果未找到,则尝试自动装载类 "A\B"new D();    // 使用导入规则,创建命名空间 "B" 中定义的类 "D" 的一个对象
            // 如果未找到,则尝试自动装载类 "B\D"new F();    // 使用导入规则,创建命名空间 "C" 中定义的类 "E" 的一个对象
            // 如果未找到,则尝试自动装载类 "C\E"new \B();   // 创建定义在全局空间中的类 "B" 的一个对象
            // 如果未发现,则尝试自动装载类 "B"new \D();   // 创建定义在全局空间中的类 "D" 的一个对象
            // 如果未发现,则尝试自动装载类 "D"new \F();   // 创建定义在全局空间中的类 "F" 的一个对象
            // 如果未发现,则尝试自动装载类 "F"// 调用另一个命名空间中的静态方法或命名空间函数B\foo();    // 调用命名空间 "A\B" 中函数 "foo"B::foo();   // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法
            // 如果未找到类 "A\B" ,则尝试自动装载类 "A\B"D::foo();   // 使用导入规则,调用命名空间 "B" 中定义的类 "D" 的 "foo" 方法
            // 如果类 "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" 中定义的类 "B" 的 "foo" 方法
              // 如果类 "A\B" 未找到,则尝试自动装载类 "A\B"?>
Nach dem Login kopieren

相关推荐:

PHP命名空间详细使用方法

PHP命名空间、性状与生成器详解

实例详解PHP命名空间用法

Das obige ist der detaillierte Inhalt vonVollständige Beherrschung von PHP-Namespaces. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
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