Подтвердить что ты не робот

Столкновения с другими методами

Как я могу иметь дело с чертами с методами одного и того же имени?

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... 

Edit:

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

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

что делать, если я хочу получить метод getRow от TooTrait через Boo? Возможно ли это?

4b9b3361

Ответ 1

Документация PHP о конфликтах:

Если две черты вставляют метод с одинаковым именем, фатальная ошибка производится, если конфликт явно не разрешен.

Для разрешения конфликтов именования между чертами, используемыми в одном классе, вместо оператора необходимо использовать, чтобы выбрать именно один из конфликтующие методы.

Поскольку это позволяет исключать только методы, оператор as может быть используется для включения одного из конфликтующих методов в другое имя.

Пример № 5: Разрешение конфликтов

В этом примере Talker использует черты A и B. Так как A и B имеют конфликтующие методы, он определяет использовать вариант smallTalk из черта B и вариант bigTalk от черты A.

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

Так что в вашем случае это может быть

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

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

(это работает, даже если вы делаете отдельный use, но я думаю, что это более понятно)

Или используйте as, чтобы объявить псевдоним.

Ответ 2

да, это возможно, вы можете использовать что-то вроде этого (ответ за отредактированный контент):

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