web-dev-qa-db-fra.com

Collisions avec d'autres méthodes de trait

Comment puis-je gérer les traits avec des méthodes du même nom?

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

erreur,

Erreur fatale: la méthode de trait getRow n'a pas été appliquée, car il y a des collisions avec d'autres méthodes de trait sur Boo dans ...

Que dois-je faire à ce sujet?

Et aussi, avec deux mêmes noms de méthode, comment puis-je obtenir la méthode de trait FooTrait?

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

Modifier:

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

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

que faire si je veux obtenir la méthode getRow de TooTrait via Boo également? C'est possible?

32
laukok

Documentation PHP sur les conflits:

Si deux Traits insèrent une méthode du même nom, une erreur fatale se produit si le conflit n'est pas résolu explicitement.

Pour résoudre les conflits de dénomination entre les traits utilisés dans la même classe, l'opérateur au lieu de doit être utilisé pour choisir exactement l'une des méthodes en conflit.

Comme cela ne permet d'exclure que des méthodes, l'opérateur as peut être utilisé pour permettre l'inclusion d'une des méthodes en conflit sous un autre nom.

Exemple # 5 Résolution de conflits

Dans cet exemple, Talker utilise les traits A et B. Comme A et B ont des méthodes conflictuelles, il définit d'utiliser la variante de Smalltalk du trait B et la variante de bigTalk du trait A.

L'Alias_Talker utilise l'opérateur as pour pouvoir utiliser l'implémentation bigTalk de B sous une conversation d'alias supplémentaire.

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

Donc, dans votre cas, cela pourrait être

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

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

(cela fonctionne même si vous séparez use, mais je pense que c'est plus clair)

Ou utilisez le as pour déclarer un alias.

59
Marco Acierno