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

为什么方法重命名在PHP中不起作用?,php,traits,Php,Traits,我使用PHP7.1.0 假设我们有一个trait,我们在类中使用它并重命名导入的方法: 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) 这真的很痛苦,因为在更复杂的

我使用PHP7.1.0

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

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

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

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

有没有办法在不从一开始就将BaseTrait::init()重命名为类似于BaseTrait::initBase()的东西的情况下解决这个问题(不仅仅是在
use
语句中)


我应该把它当作一个PHP bug来报告吗?这种行为背后有什么合理的依据吗?

如评论中所述,为了完整性;从:

别名通话器利用as操作员能够使用
B的
bigTalk
在附加别名talk下实现

然后:

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


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

php.net所写的:
别名对话者利用as操作符,能够在一个
附加的
别名对话下使用B的bigTalk实现。
-。因此,
as
添加别名,但不替换方法。然后:
as运算符可用于向其中一个方法添加别名。注意as运算符不会重命名该方法,也不会影响任何其他方法。
“@splash58 OK,谢谢。我明白了:“as”不是重命名,它只是“别名”(老实说,我在阅读这篇关于traits的文章时没有提到这个注释)。这背后有什么原因吗?我是说,用别名代替重命名有什么好处吗?在我看来,这很不方便。我认为
而不是
做你想要的。我错了吗?我不知道deep@splash58只有在同一个类中使用2个特征时(据我所知),insteadof才有效。我尝试过它,但无法将其应用于我的情况。显然,当类中的方法与trait中的方法同名时,需要使用别名。当trait方法被类的方法覆盖时,您通常不希望这样,所以使用别名。将方法
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;
}