将文件包含到名称空间中

Tyl*_* V. 4 php namespaces class include magento

我正在与Magento合作,但这不是Magento的特定问题。

假设您正在使用包含类Foo的foo.php。在Magento中,如果存在/local/foo.php,则将其包括在内;否则,将包括/core/foo.php。两者都定义了Foo类。这里的问题在于两个文件都包含类Foo,因此/local/foo.php中的类无法扩展/core/foo.php中的类。最终,这需要将/core/foo.php中的所有代码复制到/local/foo.php中,减去我的自定义内容。

/core/foo.php - 我不能改变这个文件!

<?php
class Foo {
    public function test() {
        echo 'core/foo.php :: Foo :: test';
    }
}
?>
Run Code Online (Sandbox Code Playgroud)

/local/foo_include.php

<?php
namespace mage {
    require '../core/foo.php;
}
?>
Run Code Online (Sandbox Code Playgroud)

/local/foo.php - 我不能把一个命名空间在这个文件中,因为我有文件实例化这个类没有控制权。

<?php
require './foo_include.php';

use mage;
class Foo extends mage\Foo {
    function __construct() {
        var_dump('Un-namespaced Foo!');
    }
}

$foo = new Foo();
$foo->test();
Run Code Online (Sandbox Code Playgroud)

?>

上面的方法不起作用,说法师\ Foo不存在。(如果核心Foo类是在foo_include中定义的,而不是通过include引入的,则它确实起作用。

有什么办法可以解决我所缺少的吗?

Jar*_*ell 6

通常,当我看到类似的东西时,我觉得这种方法是不正确的,需要从更高的角度检查问题。就是说,如果这是一个hack,并且您知道的话,那么对hack的这种调整将起作用。但是同样,我不建议使用任何一种方法。

将foo_include.php更改为此:

eval('namespace Mage {?>'.file_get_contents(__DIR__ . '/../core/foo.php').'}');
Run Code Online (Sandbox Code Playgroud)

我不确定Magento的工作方式,但是对于Symfony,正确的解决方案是通过参数覆盖依赖项的类。

http://symfony.com/doc/current/cookbook/bundles/override.html

Magento中有类似的东西吗?然后,您可以使用您的类覆盖该类,并扩展其他类。这仍然意味着它们需要位于不同的命名空间中,但是该框架不会尝试转到\ Foo,因为您将其覆盖了。像这样:

# original class for a dependency
dependency.class = \Foo

# overriden with new class
dependency.class = My\Foo
Run Code Online (Sandbox Code Playgroud)

然后在您的Foo版本中:

class My\Foo extends \Foo {}
Run Code Online (Sandbox Code Playgroud)

  • 哦,那很脏:-D (5认同)