PHP Laravel框架支持Model查询数据后可以有多种方式返回数据,对新手会造成一些困扰,比如数组Model对象、集合、纯数组
今天从内存占用的角度对比一下3种数据返回方式
按数组Model对象返回数据
- 写法
TestModel::query()->where('field_name', $value)->limit(10)->get()->all();
按集合返回数据
- 写法
TestModel::query()->where('field_name', $value)->limit(10)->get();
按纯数组返回数据
- 写法
TestModel::query()->where('field_name', $value)->limit(10)->get()->toArray();
测试环境
PHP 7.2.28, Docker Compose, MacOS
对比数据
- 按数量分别取10、100、1000、10000行数据来对比
返回格式 | 查询行数 | 查询结果内存占用 |
---|---|---|
Model数组 | 10 | 433.2109K |
array | 10 | 457.5313K |
Collection | 10 | 433.2891K |
Model数组 | 100 | 803.3984K |
array | 100 | 816.4688K |
Collection | 100 | 803.4766K |
Model数组 | 1000 | 4.3761M |
array | 1000 | 4.2790M |
Collection | 1000 | 4.3762M |
Model数组 | 10000 | 40.4700M |
array | 10000 | 39.2743M |
Collection | 10000 | 40.4701M |
结论
- 数据量在100以内时,用Model数组占用内存还更少
- Collection总比Model数组多一点点是因为Collection集合多了一层对象包装存储Model数组,有点鸡肋,所以我很少用这种方式
- Model数组配置IDE辅助提示时开发效率更高,并且内存占用相比纯数组array相差不大,所以建议用Model数组方式
开发建议
从开发效率和维护角度我建议选择Model数组的开发方式
因为在PhpStorm这个IDE中,Model的查询方法中加入注释 @return static[] 就可以有IDE字段辅助
当然前提是在相应Model的注释中加入属性注释 @property,下方给出几个示例
Model @property 示例
/**
* @property int $id 主键ID
* @property string $order_sn 订单号
*/
class OrderInfoModel extends Model
{
protected $table = 'order_info';
public $timestamps = false;
/**
单例入口
*/
public static function singleton()
{
return app(static::class);
}
/**
* 查找订单
* @param string $sn
* @return static
*/
public function findBySn($sn)
{
return static::query()->where('order_sn', $sn)->first();
}
/**
* 查找订单列表
* @return static[]
*/
public function findListByPage($page, $pageSize)
{
return static::query()->forPage($page, $pageSize)->get()->all();
}
}
//注意两个方法的 @return 差别
使用方法
- 以一个分页列表接口为例
class OrderController extends Controller
{
public function actionList(Request $request)
{
$page = $request->get('page', 1);
$pageSize = $request->get('size', 10);
$results = [];
$list = OrderInfoModel::singleton()->findListByPage($page, $pageSize);
if ($list) foreach ($list as $item) {
$results[] = ['order_sn' => $item->order_sn]; //在IDE中, 这个$item->order_sn是有辅助提示的,就是Model中的@property起的作用
}
//其他代码省略
}
}