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,换谁都慢~

固然呢,这些细节其实在咱们的实战系列课程里都已经讲过了,尚未上车的童鞋,你还在等什么呢?

相关文章
相关标签/搜索