laravel中get()与 first()区别、collection与stdClass的区别

本文来自pilishen.com----原文链接; 欢迎作客我们的php&Laravel学习群:109256050

最简单的,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,换谁都慢~

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值