为什么方法重命名在PHP特征中不起作用?

Dm9*_*Dm9 8 php traits

我使用PHP 7.1.0.

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

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

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

$c = new C();
$c->B();
$c->A(); // Why does it work?
Run Code Online (Sandbox Code Playgroud)

为什么PHP仍然允许我使用旧的方法名称(A在这种情况下)?

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

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;
}
Run Code Online (Sandbox Code Playgroud)

我认为,这段代码应该有效.因为我改名init()initBase()Base类和使用时,做了同样的命名规则BaseTrait里面MainTrait,我希望这个方法(BaseTrait::init())会不会产生冲突MainTrait::init().事实上,PHP说我有不兼容的声明.其背后的原因是重命名init as initBase不起作用 - 方法init仍在那里,在我Base班上!

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

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

ist*_*iuk 1

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

利用Aliased_Talkeras 运算符能够bigTalk在附加别名对话下使用 B 的实现。

进而:

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

因此as添加别名但不会以任何方式替换或影响原始方法。这是预期的行为。