UPDATE:この問題について熟考しているのは私だけではなく、確かにバグのようです。 ここ を参照してください。修正された日は素晴らしい日になるでしょう! :)
これはI love PHP traits! I'm going to use them everywhere! ^_^
として始まり、現在はThought Exercise / Learning Experience >_<
になっています。
次の例を考えてみましょう。
trait TheErrorOfYourWays{
public function booboo(){
echo 'You had a booboo :(';
}
}
trait SpectacularStuff1 {
use TheErrorOfYourWays;
}
trait SpectacularStuff2 {
use TheErrorOfYourWays;
}
class DoSomethingSpectacular {
use SpectacularStuff1, SpectacularStuff2;
}
これにより、(明らかに それほど明白ではありません):
致命的なエラー:DoSomethingSpectacularで他のトレイトメソッドとの衝突があるため、トレイトメソッドboobooは適用されていません。
それで私の質問:特性のメソッドの競合を解決するにはどうすればよいですか?重複する特性「継承」を実現することは可能ですか?もしそうなら、これを行うための「正しい」方法は何ですか?
なぜこれをしたいのか:
私が試したこと:
さまざまな場所、時間、宇宙などでの「as」、エイリアスの素晴らしい配列。以下を含みますが、これらに限定されません。
trait SpectacularStuff1 {
use TheErrorOfYourWays{
TheErrorOfYourWays::booboo as booboo1;
}
}
trait SpectacularStuff2 {
use TheErrorOfYourWays{
TheErrorOfYourWays::booboo as booboo2;
}
}
class DoSomethingSpectacular {
use SpectacularStuff1, SpectacularStuff2 {
/* Tried separately, but included here for brevity's sake */
SpectacularStuff1::booboo as booboo3;
SpectacularStuff2::booboo as booboo4;
}
}
そして
use TheErrorOfYourWays as Erroneous1;
trait SpectacularStuff1 {
use Erroneous1{
Erroneous1::booboo as booboo1;
}
}
use TheErrorOfYourWays as Erroneous2;
trait SpectacularStuff2 {
use Erroneous2{
Erroneous2::booboo as booboo2;
}
}
私はそれを理解しています:
ありがとう!
したがって、 非公式の「公式」回答 は次のとおりです。
エイリアシングなしで、または何もせずにそれを行うことができます!しかし、まだ...
5.5.1から5.5.6にアップグレードしましたが、すべて無駄でした。修正が利用可能になったら、この回答を更新します。興味深いことに、trait静的関数を直接呼び出すことができます。次の例が機能します。
trait TheErrorOfYourWays{
public static function booboo($thisTrait){
echo 'You had a booboo :( in '.$thisTrait.'<br>';
}
}
trait SpectacularStuff1 {
public function boobooTest1(){
TheErrorOfYourWays::booboo(__TRAIT__);
}
}
trait SpectacularStuff2 {
public function boobooTest2(){
TheErrorOfYourWays::booboo(__TRAIT__);
}
}
class DoSomethingSpectacular {
use SpectacularStuff1, SpectacularStuff2;
}
$boobooAChoo = new DoSomethingSpectacular();
$boobooAChoo->boobooTest1(); // You had a booboo :( in SpectacularStuff1
$boobooAChoo->boobooTest2(); // You had a booboo :( in SpectacularStuff2
はい、はい、クラスでもそれを行うことができますが、クラスは昨シーズンsooooです。
トレイトの競合を解決するには、キーワードinsteadof
を使用する必要があります。
あなたの書き直し
class DoSomethingSpectacular {
use SpectacularStuff1, SpectacularStuff2 {
/* Tried separately, but included here for brevity's sake */
SpectacularStuff1::booboo as booboo3;
SpectacularStuff2::booboo as booboo4;
}
}
to
class DoSomethingSpectacular {
use SpectacularStuff1, SpectacularStuff2
{
SpectacularStuff1::booboo insteadof SpectacularStuff2;
SpectacularStuff2::booboo insteadof SpectacularStuff1;
}
}
競合を解決します。
私はこれを一時的に修正する別の方法を見つけました:
trait A {
public function foo(){
echo 'foo';
}
}
trait B {
public function foofoo(){
return $this->foo () . 'foo';
}
}
trait C {
public function foobar(){
return $this->foo () . 'bar';
}
}
class DoSomethingSpectacular {
use A, B, C;
public function foobarfoofoo () {
echo $this->foobar () . $this->foofoo ();
}
}
そしてそれは動作します:)
ちょっとしたハック、関数booboo
をクラスDoSomethingSpectacular
に追加するだけです
<?php
trait TheErrorOfYourWays{
public function booboo(){
echo 'You had a booboo :(';
}
}
trait SpectacularStuff1 {
use TheErrorOfYourWays{
TheErrorOfYourWays::booboo as booboo1;
}
}
trait SpectacularStuff2 {
use TheErrorOfYourWays{
TheErrorOfYourWays::booboo as booboo2;
}
}
class DoSomethingSpectacular {
use SpectacularStuff1, SpectacularStuff2 {
/* Tried separately, but included here for brevity's sake */
SpectacularStuff1::booboo as booboo3;
SpectacularStuff2::booboo as booboo4;
}
//very ugly hack
public function booboo() {}
}