Eloquent 的查詢結果會回傳 Illuminate\Database\Eloquent\Collection
,而使用 collect()
會回傳 Illuminate\Support\Collection
。而且,在 Laravel 文件中,有以下資訊:
大部分的 Eloquent 集合會傳回新的「Eloquent 集合」實例,但是 pluck, keys, zip, collapse, flatten 和 flip 方法會傳回 基礎集合 實例。
對應的,如果一個 map 運算傳回一個不包含任何 Eloquent 模型的集合,那麼它將會自動轉換成基礎集合。
那麼,這兩種 Collection,或者說是「基礎集合」和「Eloquent 集合」有什麼差別呢?
看看原始碼,我們可以看到
也就是說,
IlluminateDatabaseEloquentCollection
是IlluminateSupportCollection
的子類別。你說的這幾個方法,在
IlluminateDatabaseEloquentCollection
中是这样定义的,以pluck
為例。而這裡用到的
toBase
函数在IlluminateDatabaseEloquentCollection
中没有定义,而是在IlluminateSupportCollection
中定义了。那么在子类中没有重写的方法,就会调用父类的方法。我们看看toBase
在IlluminateSupportCollection
中是如何定義的。看吧,是回傳了
new self($this)
,一个新的实例。由于这是在父类中的,自然返回的实例是IlluminateSupportCollection
了。IlluminateSupportCollection
中的pluck
定義是這樣的。而在
IlluminateSupportArr
中pluck
的定義是這樣的。回傳的是一個陣列。
這樣
IlluminateSupportCollection
中的new static(Arr::pluck)
,意思就是新建一个类的实例(new self
和new static
的差異詳見https://www.laravist.com/blog/post/php-new-static-and-new-self)。怎麼樣,現在明白了?