Php 来自traits的构造函数定义如何冲突?

Php 来自traits的构造函数定义如何冲突?,php,oop,constructor,traits,Php,Oop,Constructor,Traits,在PHP5.4.9中,以下示例触发致命错误“B具有来自traits的冲突构造函数定义” trait T { public function __construct () { echo __CLASS__ . ": constructor called.\n"; } } class A { use T; } class B extends A { use T; } 当trait包含与构造函数不同的方法时没有问题,当构造函数被实际复制到类中时也没

在PHP5.4.9中,以下示例触发致命错误“B具有来自traits的冲突构造函数定义”

trait T {
    public function __construct () {
        echo __CLASS__ . ": constructor called.\n";
    }
}

class A {
    use T;
}

class B extends A {
    use T;
}
当trait包含与构造函数不同的方法时没有问题,当构造函数被实际复制到类中时也没有问题(不使用trait,即“语言辅助复制粘贴”功能)

这里的构造函数有什么特别之处?PHP不应该知道其中一个会覆盖另一个吗?我找不到关于这个限制的任何信息


提到了一种解决问题的方法(通过为trait方法使用别名),但没有提到最初导致问题的原因。

尝试使用以下代码:

class A {
    use T;
    use T;
}
因为这是你从A扩展而来的,然后用T来表示B

如果需要在基类和子类中使用trait T,那么只在基类中使用它


如果您仅在子类中需要它,请仅在叶子类中使用它。

在这种情况下,我会收到一条不同的错误消息:“Trait method\uu构造尚未应用,因为在一个类上与其他Trait方法发生冲突”。此外,导入的方法是否是构造函数也没有区别。问题中的示例适用于其他方法,但构造函数的行为不同。@hakre没有解释为什么不同的方法看起来工作得很好。是吗?@Zilk:错误的名称不同,因为缺少扩展步骤,但两个错误都告诉您有关冲突的信息。对于其他方法,也可以尝试其他魔法方法。我可以想象,由于你不能给它们取别名,它们会有一些不同。他们依赖于他们的名字,而这个名字不能改变,所以没有别名,所以没有冲突,所以只有冲突。@hakre:我最常用的特征之一是冻结;它只有一个总是抛出异常的神奇setter(
\uu set
方法)。这是为了防止意外创建未声明的属性。即使在基类使用相同特性的派生类中,它也可以正常工作。好的,这是构造函数这是与魔法方法相关的,只是构造函数是那些魔法方法的特例。这可能是为了安全,这样PHP的运行时就不会中断(这对代码来说不安全)。