Возврат нового $ this с абстрактными классами

Я нашел некоторые проблемы с моим кодом и не понимаю, почему он делает так, как есть. Кто-нибудь может мне объяснить?

Пусть у нас есть:

abstract class AbstractThing
{
public function search(...)
{
$ret = false;

$data = $database->query(...);
foreach($data as $values)
{
$item  = new $this;
$item->fill_with_values($values);

$ret []= $item;
}

return $ret;
}
}

Он работает как задумано и возвращает экземпляры объекта при успешном поиске:

class Thing extends AbstractThing
{
// ...
}

$thing = new Thing;
$things = $thing->search(...); // Thing[] on success, false on failure

Но если я хочу немного сократить код, он ломается:

abstract class AbstractThing
{
public function search(...)
{
$ret = false;

$data = $database->query(...);
foreach($data as $values) {
$ret []= (new $this)->fill_with_values($values);
}

return $ret;
}
}

Это возвращение логическое истина. Зачем? Это хорошо работает на классах, которые не унаследованы от абстрактного класса.

3

Решение

Когда мы назначаем:

$ret []= (new $this)->fill_with_values($values);

…мы не устанавливаем $ret[] = (new $this), Вместо этого этот оператор выдвигает возвращаемое значение fill_with_values() в массив, потому что он выполняется последним.

Похоже, вы пытаетесь реализовать что-то похожее на шаблон фабричного метода. Учти это:

abstract class AbstractThing
{
...
public static function fill($values)
{
$instance = new static;
$instance->fill_with_values($values);

return $instance;
}
}

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

$ret[] = static::fill($values);

Это работает, потому что возвращаемое значение fill() является экземпляром класса, а не возвращаемым значением fill_with_values(), static Ключевое слово в этом контексте использует поздняя статическая привязка разрешить тип класса, который выполняет код (Thing в данном случае) вместо класса, который объявляет его, поэтому он работает через наследование. Увидеть этот вопрос для дополнительной информации.

2

Другие решения

Код делает 2 разные вещи:

Это добавляет $ item к вашему массиву «ret»:

        $item  = new $this;
$item->fill_with_values($values);

$ret []= $item;

Это добавляет возвращенное значение «fill_with_values» в ваш массив:

$ret []= (new $this)->fill_with_values($values);

Эквивалентом приведенного выше кода будет:

        $item  = new $this;
$return = $item->fill_with_values($values);
$ret []= $return;

Если бы я знал, что происходит в вашем методе «fill_with_values», я мог бы сказать вам, почему это логическое значение, но код не делает то же самое. Надеюсь, что это имеет смысл.

2

Хорошо, наконец, это была моя собственная ошибка. В какой-то момент была действительно возможность вернуть TRUE из функции fill_with_values ​​(). Извините за плохие вопросы и спасибо за ответы!

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector