资讯专栏INFORMATION COLUMN

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

kycool / 859人阅读

摘要:本文来自原文链接欢迎作客我们的学习群最简单的,里得到的是一组数据,得到的是一个数据。

本文来自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()后面直接调取关系,或者说不能笼统地在一堆数据上直接调取关系,那么,调取关系的正确姿势有哪些?

你可以在first() last() find() firstOrFail() findOrFail()这些具体到ID的方法后面直接取关系,比如Province::fisrt()->cities()

如果你已经get()了,也即已经有一堆数据了,那么可以遍历以后再取每一个的关系,比如:

$pros = Province::get();   //或者all()
foreach($pros as $pro){
  $pro->cities();
}

当然,如果你是要在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,换谁都慢~

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/28285.html

相关文章

  • Laravel ORM 返回数据类型小结

    摘要:一简介的数据库查询构造器提供了一个方便流畅的接口,用来创建及运行数据库查询语句。的查询构造器使用参数绑定,来保护你的应用程序免受注入的攻击。和返回的是影响行数,即失败为,成功为删除行数。 相信很多人在学习 Laravel 时,会对 ORM 返回的数据类型产生混淆,如返回集合,模或者整数类型,下面将对增删改查操作进行一个小结。 一、简介 Laravel 的数据库查询构造器提供了一个方便、...

    LeviDing 评论0 收藏0
  • Laravel & Lumen 数据库操作速查

    摘要:在中执行数据库操作有两种方式,一种是使用外观对象的静态方法直接执行查询,另外一种是使用类的静态方法实际上也是的实现,使用静态访问方式访问的方法,内部采用了魔术方法代理了对成员方法的访问。在闭包函数中,如果返回,则会停止后续的处理。 在Laravel中执行数据库操作有两种方式,一种是使用DB外观对象的静态方法直接执行sql查询,另外一种是使用Model类的静态方法(实际上也是Facade...

    用户83 评论0 收藏0
  • Laravel核心——Ioc服务容器

    摘要:服务容器在说容器之前,我们需要了解什么是容器。服务容器是一个用于管理类依赖和执行依赖注入的强大工具。几乎所有的服务容器绑定都是在服务提供者中完成,也就是在服务提供者中绑定。 服务容器 在说 Ioc 容器之前,我们需要了解什么是 Ioc 容器。 Laravel 服务容器是一个用于管理类依赖和执行依赖注入的强大工具。 在理解这句话之前,我们需要先了解一下服务容器的来龙去脉: larave...

    arashicage 评论0 收藏0
  • Laravel核心——服务容器细节特性

    摘要:前言首先欢迎关注我的博客在前面几个博客中,我详细讲了容器各个功能的使用绑定的源码解析的源码,今天这篇博客会详细介绍容器的一些细节,一些特性,以便更好地掌握容器的功能。 前言 首先欢迎关注我的博客: www.leoyang90.cn 在前面几个博客中,我详细讲了 Ioc 容器各个功能的使用、绑定的源码、解析的源码,今天这篇博客会详细介绍 Ioc 容器的一些细节,一些特性,以便更好地掌握容...

    AprilJ 评论0 收藏0
  • Laravel 5.7 最佳实践和开发技巧分享

    摘要:当查询数据时,本地范围允许我们创建自己的查询构造器链式方法。这样便会知道这是一个本地范围并且可以在查询构造器中使用。某些查询构造器不可用或者说可用但是方法名不同,关于这些请查阅所有集合的方法。 showImg(https://segmentfault.com/img/remote/1460000017877956?w=800&h=267); Laravel 因可编写出干净,可用可调试的...

    ninefive 评论0 收藏0

发表评论

0条评论

kycool

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<