2014-09-04 11 views
5

Forse questo è strano domanda, ma non riesco a lavorare fuori cosa succede internamente in PHP quando si scrive:PHP per namespace

use garcha\path\class; 

Non sto chiedendo circa scopo di spazi dei nomi, ma di questa affermazione in sé, anche se non fa alloca alcuna memoria, voglio dire, quando si dà anche un alias per un po 'di classe:

use garcha\path\class as withNewName; 

dove viene archiviata? O come ricorda i nomi? Accade solo in fase di compilazione? e non eseguire il tempo? qualcosa come la semplice descrizione della funzione.

+5

Se si ha familiarità con C, date un'occhiata alla realizzazione: http://lxr.php.net /xref/PHP_TRUNK/Zend/zend_compile.c#zend_compile_use. Ricorda i nomi memorizzandoli in una tabella hash (vedi anche zend_get_import_ht). E sì, la risoluzione alias è completamente in fase di compilazione. La VM non conosce gli alias dei nomi. – NikiC

+4

Si può vedere di persona che è tempo di compilazione, facendo un semplice script come 'Test namespace { class MyClass {}} namespace { utilizzo test \ MyClass; } e quindi usare 'phpdbg' per scaricare gli opcode. Riceverai solo un ZEND_NOP perché non c'è alcun codice di runtime lì. – Leigh

+0

lxr non funziona (maggio 2017). Utilizzare github https://github.com/php/php-src/blob/master/Zend/zend_compile.c#L6408 o avviare un contenitore docker https://hub.docker.com/r/itszero/opengrok/ – peter

risposta

2

Non è un algoritmo molto complesso (per 5.5, in 5.6 la parte descritta per i nomi di classe è la stessa).

  1. Se necessario, viene creata l'istanza di HashTable. Mantiene l'importazione (classi di spazio dei nomi utilizzate).
  2. In caso di utilizzo della parola chiave as, questo nome viene utilizzato come alias. Altrimenti ha utilizzato l'ultimo componente del nome di classe importato (per XXX \ YYY \ ZZZ, il nome sarebbe ZZZ). Convertilo in minuscolo.
  3. Verificare self/parent, non può essere utilizzato come nome per l'alias.
  4. Verificare se questo nome esiste già in class_table (utilizzando lo spazio dei nomi corrente, se è stato dichiarato).
  5. Aggiungi questo alias a HashTable speciale (citato in p.1).

Dove viene utilizzata questa tabella?

Solo durante la compilazione per la risoluzione dei nomi delle classi.

C'è una cosa più interessante di alias - ha portata come blocco dello spazio dei nomi:

<?php 

namespace nsC 
{ 
    class classC {} 
} 

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

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