将库导入类映射时如何解决类歧义?

时间:2018-10-04 13:42:03

标签: php composer-php autoload

我的项目中有一个旧的库,该库根本不使用PSR-0 / 4或任何命名空间。它包含许多具有不同类的PHP文件。假设我通过“ classmap”自动加载将此库添加到我的项目中(如Composer文档所建议的那样):

"autoload": {
    "classmap": [
        "libraries/some-lib"
    ]
}

问题在于该库不使用继承/多态性-它在不同的PHP文件中具有具有相同名称和相同方法(但这些方法的实现不同)的基类。

libraries / some-lib / Foo.php:

class Foo
{
    public function bar()
    {
        ...
    }
}

libraries / some-lib / Foo-alternate.php:

class Foo
{
    public function bar()
    {
        ...
    }
}

因此,在生成作曲家时,会为其生成类映射Ambiguous class resolution警告,由于名称冲突,我的项目代码中只能通过Foo使用\Foo的一个版本。

我的问题是在不修改库代码的情况下如何解决此问题? Composer在这种情况下是否有任何选择,以便我可以将两个版本的Foo类导入到composer的类映射中,并因此在项目中区分这两个版本?

1 个答案:

答案 0 :(得分:2)

PHP不允许两个类具有相同的名称,因此即使您会找到解决方法(例如,根据上下文从指定文件手动加载类),也比实际解决方案更像是脆弱的hack,它将失败当您尝试在同一请求中加载这两个类时。

尽管您希望避免修改库代码,但这实际上是最简单,最可靠的解决方案。进行这些更改应该很容易,而且我怀疑仍在积极开发仍未使用PSR-0 / 4的库,因此对fork的维护是否需要任何额外的工作。


  

Composer在这种情况下是否提供任何选项,以便我可以将两个版本的Foo类导入到composer的类映射中,并因此在项目中区分这两个版本?

完全限定名称(对于非命名空间的类来说,只是类名称)应该是唯一的,这是PHP的“局限性”,Composer自动加载器依赖于此。最好的选择是使用exclude-from-classmap设置忽略这些类之一:

"autoload": {
    "exclude-from-classmap": ["libraries/some-lib/Foo-alternate.php"]
}

然后,Composer将仅自动加载libraries/some-lib/Foo.php中的类。您仍然可以手动加载第二类(require __DIR__ . '/libraries/some-lib/Foo-alternate.php'),但是您应该非常小心(如果已经加载libraries/some-lib/Foo.php,将会导致致命错误)。