簡單的,laravel裡get()得到的是一組資料,first()得到的是一個model資料。
從形式上,laravel裡每一個model資料(record),在取出的時候都是用的PHP的stdClass來包裹或封裝,一個model資料就是一個stdClass,stdClass是一個沒有屬性和方法的空類,一般用來建立一個匿名對象或将非對象類型轉換成對象,這樣我們就可以很放便的操作它,動态的添加、删除屬性:
//執行個體化一個空對象
$obj = new stdClass();
//給對象動态添加屬性或者方法
$obj->name = 'pilishen.com';
$obj->description = '做全球最好的IT實戰教程';
那麼,當有多條資料取出來的時候,也即有多個stdClass的時候,我們怎麼來展現或包裹呢?就是Collection,集合的意思。

是以,進一步說,在model資料調取中,laravel first()取到的就是一個stdClass,而get()取到的是多個stdclass,無非是以Collection的形式包裹了起來,下面舉個類子列出所有省份:
可以看到,因為是取出多條資料,是以傳回的是一個
Collection{}
對象,裡面包含一個
items[]
數組(序列),在這個序列裡,裝的就是每一個
stdClass{}
對象,也即具體的每一個
Province
資料。
我們再來列印一下first()方法擷取的結果
我們可以看到first()方法得到的直接是一個stdClass對象,因為它外層沒有
array
包裹了,是以就可以直接在其上面擷取各種屬性了,比如說可以直接來調用關系(relationship)了,假設我們建立一個
Province hasMany City
的例子:
這樣我們就可以使用
Province::fisrt()->cities()
來擷取第一個省所屬的所有城市,那如果需要擷取 id為n 的省的所有城市的話我們可以使用
Province::find(n)->cities()
, 這裡的find()方法得到的也是一個具體到ID了的stdClass 對象。
這裡注意的是,關系(eloquent relationship)的調用隻能作用于某個具體的Model對象,也即你隻有具體到某個Model,某個ID,或者說某個stdclass對象了,才能進一步去調用其所屬的關系,而不能直接去一堆Model資料上調用關系,或者說不能直接在一個大的collection對象後面直接取關系, 也即這樣
Province::get()->cities()
是不對的,這相當于
Collection{}->cities()
,而這個
Collection{}
本身并沒有
cities()
這個關系屬性,雖然它裡面的每一個
Province model item
擁有這個關系屬性,但那就隔着一層了。
- 你可以在
這些具體到ID的方法後面直接取關系,比如first() last() find() firstOrFail() findOrFail()
Province::fisrt()->cities()
- 如果你已經
了,也即已經有一堆資料了,那麼可以周遊以後再取每一個的關系,比如:get()
$pros = Province::get(); //或者all()
foreach($pros as $pro){
$pro->cities();
}
- 當然,如果你是要在Blade視圖裡使用周遊後的關系資料,因為每有一個資料,就要取一次關系,就要執行一次查詢,是以你foreach裡有n個資料,就查詢n遍,就有n個query,再加上你之前get()所有資料的那1個query,是以你頁面上總共有
個query,當你資料很多的時候,就會導緻頁面特别慢,是以你一旦意識到要在視圖裡取關系屬性,就要在Controller裡提前用with方法來預加載所有的關系,例如這樣:n+1
$pros = Province::with('cities')->get(); //或者all()
foreach($pros as $pro){
$pro->cities();
}