PHP use statement for namespace
Asked Answered
C

1

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.

Confidant answered 4/9, 2014 at 19:46 Comment(3)
If you're familiar with C, take a look at the implementation: 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.Wildlife
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.Scarron
lxr is down(May 2017). Use github github.com/php/php-src/blob/master/Zend/zend_compile.c#L6408 or spin up a docker container hub.docker.com/r/itszero/opengrokTribute
B
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()
}
Boondoggle answered 7/9, 2014 at 15:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.