2014-09-04 18 views
5

Może to dziwne pytanie, ale nie mogę się dogadać co dzieje się wewnętrznie w php, gdy piszesz:PHP oświadczenie zastosowanie do nazw

use garcha\path\class; 

Nie pytam o celu nazw, ale o samo stwierdzenie, że nawet on nie przyznaje żadnej pamięci, to znaczy, jeśli nawet dać alias dla pewnej klasy:

use garcha\path\class as withNewName; 

Gdzie jest przechowywane? Albo jak pamięta nazwy? Czy dzieje się to tylko podczas kompilacji? i nie uruchamiać czasu? coś w rodzaju opisywania funkcji.

+5

Jeśli jesteś zaznajomiony z C, spojrzeć na realizację: http://lxr.php.net /xref/PHP_TRUNK/Zend/zend_compile.c#zend_compile_use. Zapamiętuje nazwy, przechowując je w hashtable (patrz także zend_get_import_ht). I tak, rozdzielczość aliasów jest w pełni kompilowana. Maszyna wirtualna nie wie o aliasach nazw. – NikiC

+4

można zobaczyć na własne oczy, że jest kompilacji poprzez prosty skrypt jak 'namespace testowej { klasy MojaKlasa {} } nazw { użycie Test \ MojaKlasa; } 'a następnie użyj' phpdbg' do zrzutu kodów opcodes. Dostaniesz tylko ZEND_NOP, ponieważ nie ma tam kodu runtime. – Leigh

+0

lxr jest wyłączony (maj 2017). Użyj github https://github.com/php/php-src/blob/master/Zend/zend_compile.c#L6408 lub zakręć kontener dokera https://hub.docker.com/r/itszero/opengrok/ – peter

Odpowiedz

2

To nie jest bardzo skomplikowany algorytm (dla 5.5, w 5.6 część opisowa dla nazw klas jest taka sama).

  1. W razie potrzeby tworzone jest wystąpienie tablicy HashTable. Zachowuje import (używane klasy przestrzeni nazw). W przypadku użycia słowa kluczowego as, nazwa ta jest używana jako alias. Else użył ostatniego składnika importowanej nazwy klasy (dla XXX \ YYY \ ZZZ, nazwa byłaby ZZZ). Konwertuj na małe litery.
  2. Sprawdź dla self/parent, nie może być używana jako nazwa dla aliasu.
  3. Sprawdź, czy ta nazwa już istnieje w class_table (przy użyciu aktualnej przestrzeni nazw, jeśli została zadeklarowana).
  4. Dodaj ten alias do specjalnego HashTable (wspomnianego w p.1).

Gdzie jest ta tabela?

Tylko podczas kompilacji do rozwiązywania nazw klas.

Jest jeszcze jedna ciekawa rzecz o aliasów - ma zakres jak blok przestrzeni nazw:

<?php 

namespace nsC 
{ 
    class classC {} 
} 

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

namespace nsB 
{ 
    // ERROR! 
    new importC(); // or \nsA\importC() 
} 
Powiązane problemy