Laravel model 查询出的对象,是否需要每次 toArray () 转换成数组?

如下:
laravel查询出的数据是对象,比如查询User信息;之前一直是不转换数组的;
直接用 $user['name'] 这种数组形式取数据的;
如果在model中定义了关联模型 comments, 页面直接使用 $user['comments'], 就能取到关联表的数据;

后来发现一个问题,如果取出来的对象不转换成数组 ;
直接嵌套遍历取数据的时候,会非常慢;

猜测:由于是对象会去执行查询是否存在关联模型,
如果转换成数组;,原来需要10秒的页面直接就变成了2秒;
标准的写法是否确实是每次都转换成array;

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 12

toArray 反正很慢 ;(

请你看看吧
https://learnku.com/docs/laravel/5.4/upgrade#upgra...

Illuminate\Database\Events\StatementPrepared event:

Event::listen(StatementPrepared::class, function ($event) {

$event->statement->setFetchMode(...);

});

6年前 评论
leo

贴下两种情况的代码看看

6年前 评论

也许 ASSOC
setFetchMode(PDO::FETCH_ASSOC)

6年前 评论

@leo
举个例子:

file

file

加上toArray()之后,时间缩短为2s;

6年前 评论

@郁弥
求解,这个是什么意思

6年前 评论

@MehrLicht 那个没有关系和时间缩短.

原来laravel Model的default fetch mode是PDO::FETCH_OBJ 所以 $user::where('id','=',$id)->get()时 result stdClass的.

要是 setFetchMode(PDO::FETCH_ASSOC) 后
get(); 的话 result 是array.

不用写最后的 ->toArray();

6年前 评论

@郁弥
上面回答 上传了一段例子图片;
不执行toArray();页面出来大概在十秒左右,
toArray()后;大概在2秒多;

框架5.3版本 config中找到了'fetch' => PDO::FETCH_OBJ,貌似改成FETCH_ASSOC并没有什么变化;

不执行toArray()出来仍然是集合;

file

file

6年前 评论

@郁弥
找到原因了.
如果使用DB:table()查询;设置fetch_assoc;确实出来是数组;
如果使用Eloquent ORM,仍然为集合;

file

6年前 评论
leo

看这代码没什么问题,可以试试最小化代码,把无关的东西去掉,看看是不是真的是这段代码引起的

6年前 评论

@MehrLicht 麻烦你了,你说得对!. 我错了

App\Providers\EventServiceProvider.php

use Illuminate\Database\Events\StatementPrepared;

public function boot()
{
    parent::boot();
    Event::listen(StatementPrepared::class, function ($event) {
        $event->statement->setFetchMode(\PDO::FETCH_ASSOC);
    });
}

MyEloquent::where('id','=',20)->get(); 的result是集合.

6年前 评论

@leo
代码应该很简单,整个页面只有这一段数据的遍历.
查询出所有数据;然后三层foreach 判断父级,输出对应数据;

如果不toArray();是对象集合;而对象是可以取到Model中定义的关联模型的,
所以是不是遍历的层级多了之后,框架取数据时,多了很多判断关联模型的步骤,才导致这么慢的;

如果频繁取类似$user['name']这种字段值时,是不是也都会判断了 'name' 是否是model中的关联模型;
而toArray()后是纯数组,只存在从数组中直接取值问题.速度就会有几倍的差距;

这样想来,如果不每次toArray()一下的话,貌似都会多消耗一些性能吧..

之前写,一直无感,都没有toArray()过;

6年前 评论

@郁弥
一直没用过呢,才发现..受教,谢谢!:+1:

6年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!