没有复制Eloquent Collection中的其他数据成员


Additional data members in Eloquent Collection not being copied

我扩展了基本的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'CollectionSupport'Collection的代码,看起来这些方法都是通过直接从Collection的项目的内部表示构造它们来创建新的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));
}

这是否意味着要复制我的元数据数组,我必须覆盖每一个方法?

扩展EloquentCollection类并不意味着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