是否可以在 spl_autoload_registry 中扩展具有相同类但路径不同的命名空间类

Posted

技术标签:

【中文标题】是否可以在 spl_autoload_registry 中扩展具有相同类但路径不同的命名空间类【英文标题】:Is it possible to extend a namespace class with same class but different path in spl_autoload_registry 【发布时间】:2014-09-15 03:34:58 【问题描述】:

我有两个命名空间类,它们使用相同的命名空间和类加载了 composer。 (PSR4)

//directory1/Foo/Bar.php
namespace Foo;

class Bar
    ....

我有第二个目录,它具有相同的覆盖命名空间。

//directory2/Foo/Bar.php
namespace Foo;

class Bar
    ....

现在,如果我将目录 1 和目录 2 都注册为自动加载程序,目录 2 将优先于目录 1。 使用这种方法,我可以通过备用目录完全覆​​盖类。

调用 new Foo\Bar 时;

我会得到一个 directory2/Foo/Bar.php 的实例

如果文件没有在第二个目录中退出,我将得到一个实例:

我会得到一个 directory1/Foo/Bar.php 的实例

这很好,但我有一个问题。

虽然我可以完全覆盖,但似乎不可能扩展以这种方式设置的类。

在 directory2/Foo 中找到的 Bar 是否可以扩展在 directory1/Foo 中找到的 Bar,因为它们共享一个命名空间和类名?

【问题讨论】:

【参考方案1】:

我强烈反对让自动加载决定加载哪个版本的类的想法。

如果您两次创建同一个类,并且两个版本之间可能存在差异,那么任何其他程序员(包括您自己一段时间后)都会混淆哪个类真正包含您的程序中使用的正确代码。

此外,所有进行大量代码索引和解析的 IDE 也会感到困惑,并表明可能使用两个可能的类。

没有人会从具有完全相同的类名但代码不同的两个不同文件中获得任何好处。

你没有说明你想用这种方法解决哪个问题,但我认为你应该这样做!在解决面向对象的编程问题时,自动加载不应发挥任何作用。

【讨论】:

我正在为 cakephp 3.0 实现一个主题。我想这样做的原因是允许主题覆盖控制器和单元格以及插件的助手。如果未指定覆盖,则单元格中的控制器应从默认位置呈现。将文件复制到主题覆盖目录非常有效,但如果我能够扩展类而不是替换它,那就太棒了。由于我要完成的工作的性质,我不可能重命名覆盖类或将原始类命名为不同的名称。只是想知道这是否可能。 您刚刚陈述了您的真实问题的主题。不要询问有关以您想要的方式解决问题的可疑方法的技术细节。询问您在为 CakePHP 创建主题时遇到的更普遍的问题。如果您将正确的标签添加到您的问题中,您可能会从 CakePHP 专家那里得到答案,他们会告诉您如何做。 :) 谢谢,我在 github 上与框架的核心开发人员进行了广泛的对话,讨论了模板和周围的约定。我想如何实现这一点的上下文并不重要,这个问题对于 php 的性质和自动加载器的工作来说是一个更基本的问题。我知道这很可能是不可能的,但我觉得有必要问一下,因为经过大量谷歌搜索后,我找不到与该主题相关的任何信息。

以上是关于是否可以在 spl_autoload_registry 中扩展具有相同类但路径不同的命名空间类的主要内容,如果未能解决你的问题,请参考以下文章

php spl_autoload_register()不加载类

spl_autoload_register() 在不同的目录

spl_autoload_register 和 __autoload()魔术方法

spl_autoload_register函数

spl_autoload_register()和__autoload()区别

使用 spl_autoload_register 处理单个文件中的多个类