6

Maybe this is weird question, but I can't work it out what happens internally in php when you write:

use garcha\path\class;

I'm not asking about purpose of namespaces, but about that statement itself, even it does not allocate any memory, I mean, when you even give an alias for some class:

use garcha\path\class as withNewName;

Where is it stored? Or how does it remember the names? Does it happen just on compile time? and not run time? something like just describing the function.

George G
  • 7,443
  • 12
  • 45
  • 59
  • 5
    If you're familiar with C, take a look at the implementation: http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_compile.c#zend_compile_use. It remembers the names by storing them in a hashtable (see also zend_get_import_ht). And yes, alias resolution is fully compile-time. The VM does not know about namespace aliases. – NikiC Sep 06 '14 at 22:40
  • 4
    You can see for yourself that it is compile time by making a simple script like `namespace Test { class MyClass {} } namespace { use Test\MyClass; }` and then use `phpdbg` to dump out the opcodes. You'll only get a ZEND_NOP because there is no runtime code there. – Leigh Sep 06 '14 at 22:43
  • lxr is down(May 2017). Use github https://github.com/php/php-src/blob/master/Zend/zend_compile.c#L6408 or spin up a docker container https://hub.docker.com/r/itszero/opengrok/ – Peter Chaula May 29 '17 at 07:51

1 Answers1

3

It's not a very complex algorithm (For 5.5, in 5.6 described part for class-names is the same).

  1. If it is necessary, instance of HashTable is created. It keeps import (used namespace classes).
  2. In case of using as keyword, this name is used as an alias. Else used last component of imported class name (for XXX\YYY\ZZZ, name would be ZZZ). Convert it to lower case.
  3. Check for self/parent, it can not be used as name for alias.
  4. Check if this name already exists in class_table (using current namespace, if it has been declared).
  5. Add this alias to special HashTable (mentioned in p.1).

Where is this table used?

Just during compilation for resolving class names.

There is one more interesting thing about aliases - it has scope as namespace block:

<?php

namespace nsC
{
    class classC {}
}

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

namespace nsB
{
    // ERROR!
    new importC(); // or \nsA\importC()
}
Yurii
  • 4,811
  • 7
  • 32
  • 41
Mark.Ablov
  • 857
  • 6
  • 6