PHP namespace and dynamic classname

ⅰ亾dé卋堺 提交于 2020-01-14 13:49:28

问题


I've encountered a "weird" thing while experimenting with spl_autoload, namespaces and dynamic class names. I use PHP 5.3.2, call the autoload like this

set_include_path(get_include_path().PATH_SEPARATOR."classes".PATH_SEPARATOR."utils");
spl_autoload_extensions(".class.php");
spl_autoload_register();

Now to the core. Suggest following code:

new \User\Student;
$name="\User\Student";
new $name();

This works fine, file classes/user/student.class.php gets loaded successfully, both constructions succeed. However, a bit different usage:

$name="\User\Student";
new $name();
new \User\Student;

fails on "..Class \User\Student could not be loaded...". I suggest it should be related to the static/dynamic namespace resolution somehow. However, I don't think there should be any difference between these two except for the time they are processed at (compilation vs. runtime).

Thanks for any explanation.


回答1:


The "problem" here is actually at a lower level than SPL, and can also be seen with __autoload(). This is best demonstrated in code:

function __autoload ($class) {
  echo "Loading $class\n";
}

new Test;
// displays "Loading Test"

$var = 'Test';
new $var;
// displays "Loading Test"

// However, when we introduce namespaces...

new \This\Is\A\Test;
// displays "Loading This\Is\A\Test"

$var = '\This\Is\A\Test';
new $var;
// displays "Loading \This\Is\A\Test"

Notice how when when introduce namespaces, the leading slash is not passed to the function when called statically, but it is when called dynamically.

The solution is therefore to do either of these fairly simple things:

  • Remove the leading slash from the dynamic class name instantiation.
  • Wrap the default spl_autoload() function like this:
set_include_path(get_include_path().PATH_SEPARATOR."classes".PATH_SEPARATOR."utils");
spl_autoload_extensions(".class.php");
spl_autoload_register(function($class) {
  spl_autoload(ltrim($class, '\\'));
});

Of course if you are doing this, you could also remove the call to spl_autoload_extensions() and just pass the ".class.php" string to the second argument of spl_autoload()



来源:https://stackoverflow.com/questions/11950517/php-namespace-and-dynamic-classname

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!