php 与其他 trait 方法的冲突

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25064470/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 17:37:42  来源:igfitidea点击:

Collisions with other trait methods

phptraitsphp-5.5

提问by laukok

How can I deal with traits with methods of same name?

如何处理具有同名方法的特征?

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();
    }
}

error,

错误,

Fatal error: Trait method getRow has not been applied, because there are collisions with other trait methods on Boo in...

致命错误:Trait 方法getRow 没有被应用,因为在Boo 上与其他trait 方法有冲突...

What should I do about it?

我该怎么办?

And also, with two same method names, how can I getthe method from trait FooTrait?

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

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

Edit:

编辑:

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

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

what if I want to get the method getRowfrom TooTraitvia Booas well? Is it possible?

如果我也想getRowTooTraitvia获取方法Boo怎么办?是否可以?

回答by Marco Acierno

PHP Documentation about conflicts:

关于冲突的 PHP 文档:

If two Traits insert a method with the same name, a fatal error is produced, if the conflict is not explicitly resolved.

To resolve naming conflicts between Traits used in the same class, the insteadof operator needs to be used to chose exactly one of the conflicting methods.

Since this only allows one to exclude methods, the as operator can be used to allow the inclusion of one of the conflicting methods under another name.

Example #5 Conflict Resolution

In this example, Talker uses the traits A and B. Since A and B have conflicting methods, it defines to use the variant of smallTalk from trait B, and the variant of bigTalk from trait A.

The Aliased_Talker makes use of the as operator to be able to use B's bigTalk implementation under an additional alias talk.

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

要解决同一类中使用的 Traits 之间的命名冲突,需要使用替代运算符来选择冲突方法之一。

由于这仅允许排除方法,因此 as 运算符可用于允许以另一个名称包含冲突方法之一。

Example #5 冲突解决

在这个例子中,Talker 使用了 trait A 和 B。由于 A 和 B 的方法有冲突,它定义了使用来自 trait B 的 smallTalk 的变体,以及来自 trait A 的 bigTalk 的变体。

Aliased_Talker 使用 as 运算符,以便能够在附加别名谈话下使用 B 的 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;
    }
}

So in your case it could be

所以在你的情况下可能是

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

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

(it works even if you do separate use, but i think it's more clear)

即使你分开它也能工作use,但我认为它更清楚

Or use the asto declare an alias.

或者使用as来声明别名。

回答by Neznajka

yes this is possible you can use something like this (answer for edited content) :

是的,这是可能的,你可以使用这样的东西(编辑内容的答案):

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);
    }
}