简单的,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拥有这个关系属性,但那就隔着一层了。

好吧,不能在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,换谁都慢~

laravel中get()与 first()区别、collection与stdClass的区别的更多相关文章

  1. 介绍Collection框架的结构;Collection 和 Collections的区别

    介绍Collection框架的结构:Collection 和 Collections的区别 集合框架: Collection:List列表,Set集 Map:Hashtable,HashMap,Tre ...

  2. Laravel中的队列处理

    Laravel中的队列处理 队列介绍 为什么要有消息队?这里先对其进行一个简单的介绍,方便还不了解的同学理解.在面向对象里,有一个很简单的概念--消息传递,而消息队列就可以在它上面扩展一下,把它说的更 ...

  3. Laravel中服务提供者和门面模式

    在laravel中,我们可能需要用到自己添加的类时,可以建立一个文件夹专门存放类文件,也可以使用laravel的服务提供者的方式来使用. 这两者其实区别不大,主要是前者使用的话,会跟业务代码产生依赖, ...

  4. 统计分析中Type I Error与Type II Error的区别

    统计分析中Type I Error与Type II Error的区别 在统计分析中,经常提到Type I Error和Type II Error.他们的基本概念是什么?有什么区别? 下面的表格显示 b ...

  5. Python中内置数据类型list,tuple,dict,set的区别和用法

    Python中内置数据类型list,tuple,dict,set的区别和用法 Python语言简洁明了,可以用较少的代码实现同样的功能.这其中Python的四个内置数据类型功不可没,他们即是list, ...

  6. Laravel中的日志与上传

    PHP中的框架众多,我自己就接触了好几个.大学那会啥也不懂啥也不会,拿了一个ThinkPHP学了.也许有好多人吐槽TP,但是个人感觉不能说哪个框架好,哪个框架不好,再不好的框架你能把源码读上一遍,框架 ...

  7. 程序代码中退出函数exit()与返回函数return ()的区别

    程序代码中退出函数exit()与返回函数return ()的区别   exit(0):正常运行程序并退出程序:   exit(1):非正常运行导致退出程序:   return():返回函数,若在主函数 ...

  8. C#中 Request, Request.params , Request.querystring , Request.Form 区别 与联系用法

    C#中 Request, Request.params , Request.querystring , Request.Form 区别 与联系用法? Request.params , Request ...

  9. laravel中日志为daily时如何设置最大保存天数

    在laravel中,日志设置为daily时,默认保存七天的日志,超过则清除七天前的日志.可修改默认的设置,假如要保存30天的日志,则配置如下: 在配置文件config/app.php中添加如下代码: ...

随机推荐

  1. Terraria(泰拉瑞亚)存档覆盖(Linux)

    这是一篇关于游戏的不正经博客 ~ 游戏介绍: <泰拉瑞亚>是由Re-Logic公司开发的一款高自由度的沙盒游戏,于2011年5月16日在PC上发行. 玩家可以在游戏中做很多事情:制造武器战 ...

  2. zoj3781

    zoj3781赛场上堵在了缩点上emmmmm把原始图相同颜色的方块缩成一个点,然后与它周围不同颜色的联通块连双向边,然后枚举每个点然后求最大深度的最小值因为每次翻转都相当于深度+1(可以手动模拟一下 ...

  3. pandas 数据处理实例

    描述:行标签为日期,列标签为时间,表哥的值是 float 的数值# 一. 读取 csv 文件df=pd.read_csv("delay_3.csv",encoding = &quo ...

  4. Windows下利用MKL加速caffe,与openblas比较

    一.介绍:先简单Mark一下网上的介绍资料,弄清楚MKL是个啥,已经与openblas等的关系. 矩阵运算库blas, cblas, openblas, atlas, lapack, mkl之间有什么 ...

  5. [BZOJ1045][HAOI2008]糖果传递 (环形均分纸牌)

    题意 有n个小朋友坐成一圈,每人有ai个糖果.每人只能给左右两人传递糖果.每人每次传递一个糖果代价为1. 思路 把|s[i]-s[k]|求和即可,s[i]是A的前缀和 s[k]为s数组的中位数时,总值 ...

  6. SEED实验——Environment Variable and Set-UID Program实验描述与实验任务

    第一部分:实验描述 该实验的学习任务是理解环境变量是如何影响程序和系统行为的.环境变量是一组动态命名的变量 第二部分:实验任务 2.1 任务一:操作环境变量 在这个任务中,我们研究可以用来设置和取消设 ...

  7. c++第五周学习小结

    上周快乐的国庆假期有令我不太快乐的C++作业,我还是坚强的把它完成了.做C++就是在快乐和不快乐徘徊的过程.当你慢慢摸索写出正确答案时获得的成就感还是很开心的,但是当你苦苦思考还是无法完成时简直是狂躁 ...

  8. php发送邮箱重置密码链接,并在重置成功后使链接失效 (ThinkPHP5)

    /** * 重置密码页,验证链接有效性,页面发送邮件调用sendResetPwdEmail()方法 */ public function resetPwd() { $param = input('') ...

  9. 小甲鱼零基础python课后题 P22 021函数:递归是神马

    0.递归在编程上的形式是如何表现的呢? 答:在编程上,递归表现为函数调用本身这么一个行为. 1.递归必须满足哪两个基本条件? 答:1函数调用自己. 2有正确的返回条件 2.思考一下,按照递归的特性,在 ...

  10. (转)JDK 1.8 预览版Lambda语法分析

    一.lambda含义     lambda表示数学符号“λ”,计算机领域中λ代表“λ演算”,表达了计算机中最基本的概念:“调用”和“置换”.在很多动态语言和C#中都有相应的lambda语法,这类语法都 ...