2014-09-04 30 views
5

Vielleicht ist diese seltsame Frage, aber ich kann es nicht herausfinden, was intern in php passiert, wenn Sie schreiben:PHP-Anweisung für Namespace

use garcha\path\class; 

Ich bin nicht über Zweck der Namensräume zu fragen, sondern um diese Aussage selbst, auch nicht auf diese auf keinen Speicher, ich meine, wenn Sie auch ein Alias ​​für einige Klasse geben:

use garcha\path\class as withNewName; 

Wo ist es gespeichert? Oder wie erinnert es sich an die Namen? Tritt es nur zur Kompilierzeit auf? und keine Laufzeit? etwas, das nur die Funktion beschreibt.

+5

Wenn Sie mit C vertraut sind, nehmen Sie einen Blick auf die Umsetzung: http://lxr.php.net /xref/PHP_TRUNK/Zend/zend_compile.c#zend_compile_use. Er speichert die Namen in einer Hashtabelle (siehe auch zend_get_import_ht). Und ja, Alias-Auflösung ist vollständig Kompilierzeit. Die VM kennt keine Namespace-Aliase. – NikiC

+4

Sie können selbst sehen, dass es Zeit ist, kompilieren, indem ein einfaches Skript wie 'Namespace-Test machen { class MyClass {}} Namespace { Verwendung Test \ MyClass; } 'und dann' phpdbg' verwenden, um die Opcodes auszugeben. Sie erhalten nur einen ZEND_NOP, da dort kein Laufzeitcode vorhanden ist. – Leigh

+0

lxr ist down (Mai 2017). Verwende github https://github.com/php/php-src/blob/master/Zend/zend_compile.c#L6408 oder starte einen Docker-Container https://hub.docker.com/r/itszero/opengrok/ – peter

Antwort

2

Es ist kein sehr komplexer Algorithmus (Für 5.5, in 5.6 beschriebenen Teil für Klassennamen ist das gleiche).

  1. Wenn es notwendig ist, wird Instanz von HashTable erstellt. Es behält den Import (verwendete Namespace-Klassen).
  2. Bei Verwendung des Schlüsselwortes as wird dieser Name als Aliasname verwendet. Else hat die letzte Komponente des importierten Klassennamens verwendet (für XXX \ YYY \ ZZZ wäre der Name ZZZ). Konvertieren Sie es in Kleinbuchstaben.
  3. Überprüfen Sie für /parent, es kann nicht als Name für Alias ​​verwendet werden.
  4. Überprüfen Sie, ob dieser Name in class_table bereits vorhanden ist (unter Verwendung des aktuellen Namespace, wenn dieser deklariert wurde).
  5. Fügen Sie diesen Alias ​​zu einer speziellen HashTable hinzu (auf Seite 1 erwähnt).

Wo wird diese Tabelle verwendet?

Nur während der Kompilierung zum Auflösen von Klassennamen.

Es gibt eine weitere interessante Sache über Aliase - es hat Umfang als Namespace-Block:

<?php 

namespace nsC 
{ 
    class classC {} 
} 

namespace nsA 
{ 
    use nsC\classC as importC; 
    new importC(); 
} 

namespace nsB 
{ 
    // ERROR! 
    new importC(); // or \nsA\importC() 
}