laravel中get()與 first()區別、collection與stdClass的區別

本文來自pilishen.com---- 原文連接; 歡迎做客咱們的php&Laravel學習羣:109256050

最簡單的,laravel裏get()獲得的是一組數據,first()獲得的是一個model數據。php

從形式上,laravel裏每個model數據(record),在取出的時候都是用的PHP的stdClass來包裹或封裝,一個model數據就是一個stdClass,stdClass是一個沒有屬性和方法的空類,通常用來建立一個匿名對象或將非對象類型轉換成對象,這樣咱們就能夠很放便的操做它,動態的添加、刪除屬性:laravel

//實例化一個空對象
$obj = new stdClass();
//給對象動態添加屬性或者方法
$obj->name = 'pilishen.com';
$obj->description = '作全球最好的IT實戰教程';

那麼,當有多條數據取出來的時候,也即有多個stdClass的時候,咱們怎麼來展示或包裹呢?就是Collection,集合的意思。數組

因此,進一步說,在model數據調取中,laravel first()取到的就是一個stdClass,而get()取到的是多個stdclass,無非是以Collection的形式包裹了起來,下面舉個類子列出全部省份:post

能夠看到,由於是取出多條數據,因此返回的是一個Collection{}對象,裏面包含一個items[]數組(序列),在這個序列裏,裝的就是每個stdClass{}對象,也即具體的每個Province數據。性能

咱們再來打印一下first()方法獲取的結果學習

咱們能夠看到first()方法獲得的直接是一個stdClass對象,由於它外層沒有array包裹了,因此就能夠直接在其上面獲取各類屬性了,好比說能夠直接來調用關係(relationship)了,假設咱們建立一個 Province hasMany City 的例子:spa

這樣咱們就可使用 Province::fisrt()->cities()來獲取第一個省所屬的全部城市,那若是須要獲取 id爲n 的省的全部城市的話咱們可使用 Province::find(n)->cities(), 這裏的find()方法獲得的也是一個具體到ID了的stdClass 對象。3d

這裏注意的是,關係(eloquent relationship)的調用只能做用於某個具體的Model對象,也即你只有具體到某個Model,某個ID,或者說某個stdclass對象了,才能進一步去調用其所屬的關係,而不能直接去一堆Model數據上調用關係,或者說不能直接在一個大的collection對象後面直接取關係, 也即這樣Province::get()->cities()是不對的,這至關於Collection{}->cities(),而這個Collection{}自己並無cities()這個關係屬性,雖然它裏面的每個Province model item擁有這個關係屬性,但那就隔着一層了。code

好吧,不能在get()後面直接調取關係,或者說不能籠統地在一堆數據上直接調取關係,那麼,調取關係的正確姿式有哪些?對象

  1. 你能夠在first() last() find() firstOrFail() findOrFail()這些具體到ID的方法後面直接取關係,好比Province::fisrt()->cities()
  2. 若是你已經get()了,也即已經有一堆數據了,那麼能夠遍歷之後再取每個的關係,好比:
$pros = Province::get();   //或者all()
foreach($pros as $pro){
  $pro->cities();
}
  1. 固然,若是你是要在Blade視圖裏使用遍歷後的關係數據,由於每有一個數據,就要取一次關係,就要執行一次查詢,因此你foreach裏有n個數據,就查詢n遍,就有n個query,再加上你以前get()全部數據的那1個query,因此你頁面上總共有n+1個query,當你數據不少的時候,就會致使頁面特別慢,因此你一旦意識到要在視圖裏取關係屬性,就要在Controller裏提早用with方法來預加載全部的關係,例如這樣:
$pros = Province::with('cities')->get();   //或者all()
foreach($pros as $pro){
  $pro->cities();
}

這樣的話,一次性地取得了全部省份以及每一個省份下面的城市關係,背後只是執行了2次query,你在視圖裏再去遍歷的時候,就不用再執行數據查詢了,性能就會有較大提高。

不少小白抱怨laravel視圖加載慢,不知道他們有沒有查看一下本身頁面的query執行狀況呢?一個視圖查詢太多的query,換誰都慢~

固然呢,這些細節其實在咱們的實戰系列課程裏都已經講過了,尚未上車的童鞋,你還在等什麼呢?

相關文章
相關標籤/搜索