Я расширил основной Eloquent\Collection
Класс следующим образом:
class BoogerCollection extends \Illuminate\Database\Eloquent\Collection {
// Metadata used by my collection
protected $some_array = [];
public function setArray(){
$this->some_array = [1,2,3];
}
public function getArray(){
return $this->some_array;
}
}
Итак, следующие работы, как и ожидалось:
$collection = new BoogerCollection();
$collection->setArray();
print_r($collection->getArray()); // Prints out Array ( [0] => 1 [1] => 2 [2] => 3 )
Однако если я затем выполню некоторую операцию над коллекцией, которая возвращает измененную копию коллекции, эти метаданные будут потеряны:
// Perform some operation on the collection that makes a copy
$collection = $collection->reverse();
print_r($collection->getArray()); // Prints out Array ( )
Так что мой $some_array
участник не копируется. Я копался в коде для Eloquent\Collection
а также Support\Collection
и похоже, что все эти методы создают новые Коллекции, напрямую создавая их из внутреннего представления Коллекции элементов:
в Eloquent Support\Collection
:
public function reverse()
{
// $this->items is the Collection's internal representation of the collection of items
return new static(array_reverse($this->items));
}
Означает ли это, что для того, чтобы скопировать и мой массив метаданных, я должен переопределить каждый отдельный метод?
простирающийся Eloquent
«s Collection
класс не означает, что он будет использоваться Eloquent
вернуть коллекцию моделей. Теперь, Eloquent
будет придерживаться его Collection
класс, который Illuminate\Database\Eloquent\Collection
при возврате коллекции. Если вы посмотрите на Illuminate\Database\Eloquent\Builder
коды, вы увидите методы, которые возвращают коллекцию (get()
, findMany()
и т. д.) вызовет поставляемую модель newCollection()
метод, который в свою очередь возвращает экземпляр Illuminate\Database\Eloquent\Collection
а не ваш недавно созданный подкласс.
Ваш код: $collection = new BoogerCollection();
работает, потому что вы тот, кто создал свой класс. Но когда делаешь что-то вроде MyModel::all()
не вернет ваш BoogerCollection
класс как Eloquent
будет один, чтобы выбрать то, что Collection
класс, который он хочет вернуть, и сейчас он придерживается Illuminate\Database\Eloquent\Collection
,
Других решений пока нет …