15

我注意到,当我使用命名空间时,动态加载类与静态加载类的工作方式不同。因此,例如,在不使用命名空间的情况下,以下在实例化名为 的类的操作中是等效的FooBar

$foobar = new FooBar();

$classname = "FooBar";
$foobar = new $classname;

但是,如果在使用命名空间时我有一些这样的代码:

<?php

namespace Structure\Library;

$foobar = new UserService();
$classname = "UserService";
$barfoo = new $classname;

在这种情况下,UserService类的完全限定名称是Structure\Library\UserService,如果我使用完全限定名称,它在这两种情况下都有效,但如果我只使用它的快捷方式名称,'UserService'在使用静态方法实例化时才有效。有没有办法让它对两者都有效?

PS我正在为所有类使用自动加载器......但我假设问题发生自动加载器之前并且正在影响传递给自动加载器的类字符串。

4

3 回答 3

13

我认为这是一个阅读文档的案例。参见示例 3:

http://php.net/manual/en/language.namespaces.importing.php

似乎证实了我之前的评论。

<?php
    namespace foo\bar;

    $classStr = "myClass";    
    $nsClass = "\\foo\\bar\\myClass";

    $x = new myClass;    // instantiates foo\bar\myClass, because of declared namespace at top of file
    $y = new $classStr;  // instantiates \myClass, ignoring declared namespace at top of file
    $z = new $nsClass    // instantiates foo\bar\myClass, because it's an absolute reference!
?>
于 2013-10-02T17:12:46.373 回答
5

这将是我能找到的最接近的解决方案:

define('__NSNAME__', __NAMESPACE__.'\\');

$foobar = new UserService();
$classname = __NSNAME__."UserService";
$barfoo = new $classname;

祝你好运!

更新 1

这可能有助于进一步阅读:http ://www.php.net/manual/en/language.namespaces.importing.php

use My\Full\UserService as UserService;

更新 2

这是我现在走了多远:

namespace Structure\Library\Home;

class UserService {

}

namespace Structure\Library;

use Structure\Library\Home\UserService as UserService;

define('UserService', __NAMESPACE__.'\\Home\\UserService', TRUE);

$foobar = new UserService();
$classname = UserService;
$barfoo = new $classname;

或者这个变体以获得更大的灵活性:

define('Home', __NAMESPACE__.'\\Home\\', TRUE);

$foobar = new UserService();
$classname = Home.'UserService';
$barfoo = new $classname;

文档

于 2013-03-22T18:32:28.800 回答
0

以下动态将$barfoo实例化为Structure\Library\UserService对象:

namespace Structure\Library;

$classname = __NAMESPACE__ . "\\" . "UserService";
$barfoo = new $classname;
于 2020-02-18T22:25:03.420 回答