Я нашел некоторые проблемы с моим кодом и не понимаю, почему он делает так, как есть. Кто-нибудь может мне объяснить?
Пусть у нас есть:
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;
}
}
Это возвращение логическое истина. Зачем? Это хорошо работает на классах, которые не унаследованы от абстрактного класса.
Когда мы назначаем:
$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 разные вещи:
Это добавляет $ 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», я мог бы сказать вам, почему это логическое значение, но код не делает то же самое. Надеюсь, что это имеет смысл.
Хорошо, наконец, это была моя собственная ошибка. В какой-то момент была действительно возможность вернуть TRUE из функции fill_with_values (). Извините за плохие вопросы и спасибо за ответы!