与其他特质方法的碰撞

时间:2014-07-31 16:38:38

标签: php traits php-5.5

如何使用同名方法处理特征?

trait FooTrait {
  public function fooMethod() {
        return 'foo method';
  }

  public function getRow() {
        return 'foo row';
  }
}

trait TooTrait {
    public function tooMethod() {
        return 'too method';
    }

    public function getRow() {
        return 'too row';
    }
}

class Boo
{
    use FooTrait;
    use TooTrait;

    public function booMethod() {
        return $this->fooMethod();
    }
}

误差,

  

致命错误:Trait方法getRow尚未应用,因为那里   与Boo中的其他特质方法发生碰撞...

我该怎么办呢?

另外,使用两个相同的方法名称,我如何从trait FooTrait 获取方法?

$a = new Boo;
var_dump($a->getRow()); // Fatal error: Call to undefined method Boo::getRow() in... 

修改

class Boo
{
    use FooTrait, TooTrait {
        FooTrait::getRow insteadof TooTrait;
    }

    public function booMethod() {
        return $this->fooMethod();
    }
}

如果我想通过getRowTooTrait获取方法Boo该怎么办?有可能吗?

2 个答案:

答案 0 :(得分:56)

关于冲突的PHP文档:

  

如果两个Traits插入一个名称相同的方法,则会出现致命错误   如果冲突没有明确解决,就会产生。

     

要解决同一类中使用的Traits之间的命名冲突,请执行以下操作:   而不是运营商需要用来选择其中一个   矛盾的方法。

     

由于这只允许排除方法,因此as运算符可以   过去允许包含一个冲突的方法   另一个名字。

     

示例#5冲突解决

     

在这个例子中,Talker使用特征A和B.因为A和B有   冲突的方法,它定义使用来自smallTalk的变体   特质B,以及来自特质A的bigTalk变体。

     

Aliased_Talker使用as运算符来使用B' s   另外一个别名谈话下的bigTalk实现。

<?php
trait A {
    public function smallTalk() {
        echo 'a';
    }

    public function bigTalk() {
        echo 'A';
    }
}

trait B {
    public function smallTalk() {
        echo 'b';
    }

    public function bigTalk() {
        echo 'B';
    }
}

class Talker {
    use A, B {
        B::smallTalk insteadof A;
        A::bigTalk insteadof B;
    }
}

class Aliased_Talker {
    use A, B {
        B::smallTalk insteadof A;
        A::bigTalk insteadof B;
        B::bigTalk as talk;
    }
}

所以在你的情况下它可能是

class Boo {
    use FooTrait, TooTrait {
        FooTrait::getRow insteadof TooTrait;
    }

    public function booMethod() {
        return $this->fooMethod();
    }
}

即使你单独use也有效,但我认为它更清晰

或使用as声明别名。

答案 1 :(得分:1)

是的,您可以使用类似以下内容(针对已编辑内容的答案):

class Boo {
    use FooTrait, TooTrait {
        FooTrait::getRow as getFooRow;
        TooTrait::getRow as getTooRow;
    }

    public function getRow(... $arguments)
    {
         return [ 'foo' => $this->getFooRow(... $arguments), 'too' => $this->getTooRow(... $arguments) ];
    }

    public function booMethod(... $arguments)
    {
        return $this->getFooRow(... $arguments);
    }
}