为什么方法重命名在 PHP 特征中不起作用? [英] Why method renaming does not work in PHP traits?

查看:31
本文介绍了为什么方法重命名在 PHP 特征中不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 PHP 7.1.0.

I use PHP 7.1.0.

假设我们有一个 trait,我们在类中使用它并重命名导入的方法:

Let's say we have a trait, we use it inside a class and rename the imported method:

trait T
{
    public function A() {
        echo ".";
    }
}

class C
{
    use T {
        A as B;
    }
}

$c = new C();
$c->B();
$c->A(); // Why does it work?

为什么 PHP 仍然允许我使用旧的方法名称(在本例中为 A)?

Why does PHP still allow me to use old method name (A in this case)?

这真的很痛苦,因为在更复杂的例子中你不能依赖方法重命名——因此你可能会意外收到不兼容的声明"错误:

It's really a pain because in more complex examples you cannot rely on method renaming - and thus you can unexpectedly receive "incompatible declarations" error:

class BaseSrc
{
}

trait BaseTrait
{
    public function init(BaseSrc $baseSrc)
    {
        echo "Init Base";
    }
}

class Base
{
    use BaseTrait {
        BaseTrait::init as initBase;
    }
}

$base = new Base();
$base->initBase(new BaseSrc());
$base->init(new BaseSrc()); // WHY DOES IT WORK?????

class MainSrc extends BaseSrc
{
}

trait MainTrait
{
    use BaseTrait {
        BaseTrait::init as initBase;
    }

    public function init(MainSrc $mainSrc)
    {
        $this->initBase($mainSrc);
        echo "Init Main";
    }
}

// Warning: Declaration of MainTrait::init(MainSrc $mainSrc) should be compatible with Base::init(BaseSrc $baseSrc)
class Main extends Base
{
    use MainTrait;
}

我认为,这段代码应该可以工作.因为我在 Base 类中将 init() 重命名为 initBase() 并且在使用 BaseTrait 时做了同样的重命名在 MainTrait 中,我希望这个方法 (BaseTrait::init()) 不会与 MainTrait::init() 冲突.事实上,PHP 说我有不兼容的声明.其背后的原因是将 init 重命名为 initBase 不起作用 - 方法 init 仍然存在,在我的 Base 类中!

I think, this code should work. Since I renamed init() into initBase() in the Base class AND did the same renaming when using BaseTrait inside MainTrait, I expect that this method (BaseTrait::init()) will not conflict with MainTrait::init(). In fact, PHP says that I have incompatible declarations. The reason behind it is that renaming init as initBase does not work - method init is still there, in my Base class!

有没有办法解决这个问题,而无需从一开始就将 BaseTrait::init() 重命名为 BaseTrait::initBase() 之类的东西(不仅仅是在 use 语句中)?

Is there any way how to solve this problem without renaming BaseTrait::init() into something like BaseTrait::initBase() from the very beginning (not just in the use statement)?

我应该将此视为 PHP 错误并报告吗?这种行为背后有什么合理的吗?

Should I consider this as a PHP bug and report it? Is there anything reasonable behind this behaviour?

推荐答案

正如评论中提到的,为了完整性;来自 关于特性的 PHP 手册部分:

As mentioned in the comments and for completeness; From the PHP manual section on Traits:

Aliased_Talker 使用 as 操作符可以使用B 的 bigTalk 在附加别名谈话下的实现.

The Aliased_Talker makes use of the as operator to be able to use B's bigTalk implementation under an additional alias talk.

然后:

as 运算符可用于向其中一种方法添加别名.请注意 as 运算符不会重命名方法,也不会影响任何其他方法.

The as operator can be used to add an alias to one of the methods. Note the as operator does not rename the method and it does not affect any other method either.

所以 as 添加了一个别名,但不会以任何方式替换或影响原始方法.这是预期的行为.

So as adds an alias but does not replace or affect the original method in any way. This is the expected behavior.

这篇关于为什么方法重命名在 PHP 特征中不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆