我使用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?
为什么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;
}
我认为,这段代码应该有效。自从我在init()
类中将initBase()
重命名为Base
并在BaseTrait
中使用MainTrait
时进行相同的重命名,我希望这种方法(BaseTrait::init()
)不会与MainTrait::init()
冲突。事实上,PHP说我有不兼容的声明。其背后的原因是重命名init as initBase
不起作用 - 方法init
仍然存在,在我的Base
类!
有没有办法如何解决这个问题,而不是从一开始就将BaseTrait :: init()重命名为BaseTrait :: initBase()(不仅仅是在use
语句中)?
我应该将此视为PHP错误并报告吗?这种行为背后有什么合理的吗?
正如评论中所述和完整性;来自PHP manual section on Traits:
Aliased_Talker
利用as运算符能够在另外的别名谈话中使用B的bigTalk
实现。
然后:
as运算符可用于向其中一个方法添加别名。请注意,as运算符不会重命名该方法,也不会影响任何其他方法。
所以as
添加了一个别名,但不会以任何方式替换或影响原始方法。这是预期的行为。