Eloquent Collection中的其他数据成员未被复制

I have extended the basic Eloquent\Collection class as follows:

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

So, the following works as expected:

$collection = new BoogerCollection();
$collection->setArray();
print_r($collection->getArray());   // Prints out Array ( [0] => 1 [1] => 2 [2] => 3 )

However, if I then perform some operation on the collection which returns a modified copy of the collection, this metadata gets lost:

// Perform some operation on the collection that makes a copy
$collection = $collection->reverse();
print_r($collection->getArray());      // Prints out Array ( )

So, my $some_array member is not getting copied. I dug into the code for Eloquent\Collection and Support\Collection, and it looks like these methods all create new Collections by directly constructing them from the Collection's internal representation of the items:

in Eloquent's 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));
}

Does this mean that to have my metadata array copied as well, I must override every single method?

Extending Eloquent's Collection class doesn't mean it will be used by Eloquent to return a collection of models. For now, Eloquent will stick with it's Collection class, which is Illuminate\Database\Eloquent\Collection when returning a collection. If you look at Illuminate\Database\Eloquent\Builder's codes, you'll see the methods that returns a collection (get(), findMany(), etc.) will call the supplied model's newCollection() method which in turn returns an instance of Illuminate\Database\Eloquent\Collection and not your newly created subclass.

Your code: $collection = new BoogerCollection(); works because you're the one who instantiated your class. But when doing something like MyModel::all() won't return your BoogerCollection class as Eloquent will be the one to choose what Collection class it wants to return and right now it sticks with Illuminate\Database\Eloquent\Collection.