在另一个命名空间中覆盖具有相同类的对象创建

时间:2016-07-08 14:28:39

标签: php namespaces autoload

尝试创建特定的类时,我试图欺骗PHP从另一个命名空间中获取一个类。

我有两个名为" page"的类,第一个在Core名称空间中:

namespace Core;
class Page {...}

第二个继承自Core \ Page,但添加了一些东西。它位于Addons名称空间中。

namespace Addons;
class Page extends \Core\Page{...}

我想这样做的原因是因为我想用一个简单的插件引擎来构建我的系统。无论何时,我都可以在XML文件中添加一行,告诉自动加载函数将类添加到addon命名空间而不是核心命名空间。

然而,当我尝试这样做时:

spl_autoload_register('loadClass');

public function loadClass(string $className)
{
    if (Addon_exist_and_is_registered($className))
    {
        require "/Addons/$className.php";
    }
    else
    {
        require "/Core/$className.php";
    }
}

$page = new \Core\Page(); <-- error here

我收到一条错误消息,指出在Addons \ Page.php文件中找不到类\ Core \ Page。这是正常行为,因为类不在同一名称空间中,因此,完全限定名称无法找到正确的类。

是否有可能欺骗PHP认为另一个命名空间中的子类实际上是正确的类?我为插件类尝试了这个;

namespace Core;
class Page extends \Core\Page{...}

但它打破了继承,因为你无法继承自己。

1 个答案:

答案 0 :(得分:2)

忽略这些类具有“相同名称”。因为他们没有。一个类称为Core\Page,另一个类称为Addons\Page这些是他们的名字,他们的完全限定的名称是准确的。它与FooBar的区别很大。如果你告诉PHP实例化Core\Page,那么它会这样做;你不能“欺骗”它来实例化Addons\Page,因为那是一个完全不同的类名。

不要试图“欺骗”任何人,让你的系统实际上是可扩展的,并明确允许覆盖类名:

$class = 'Core\Page';
if (...) {
    $class = 'Addons\Page';
}

$page = new $class;