Yii2框架踩坑记录-数组数据渲染到后台页面带分页

不得不说Yii框架还是一个非常高效的框架,Gii扩展能生成简单的CRUD操作,问题也就出在这里,我的数据不是直接从单独的表出来的,需要连查,需要递归操作

PM前两天说的是统计一下这段时间用户的邀请人数,好,没问题,写个脚本自动定时跑吧

测试以后没有问题就给推到线上去了,PM是不可能不给需求的

好,给后台加上一个直推人数排名,WTF?不是有直推人数的字段吗?我要指定时间段的数据~

不要给我说什么底层原理、框架内核!老夫敲代码就是一把梭!Ctrl+C Ctrl+V 拿起键盘就是干!

先去把我脚本的代码复制过来

$orderModel = new OrderModel;
$orders = $orderModel::find()
    ->joinWith('orderGoods')
    ->joinWith('user')
    ->Where(['>=','{{%order}}.pay_at',$startTime])
    ->andWhere(['<','{{%order}}.pay_at',$endTime])
    ->andWhere(['{{%order_goods}}.acttype'=>1])
    ->andWhere(['>','{{%user}}.inv_id',0])
    ->andWhere(['in', '{{%order}}.status', [2,3,4]])
    ->all();
$invArr = $this->getInvId($orders); // 得到在regtime之后 注册用户的inv_id
$invNums = array_count_values($invArr);  // 返回一个数组,该数组用数组中的值作为键名,该键值是在数组中出现的次数
arsort($invNums);

getInvId方法就是之前说递归的时候的方法,得到数组$invNums,该数组用$invArr数组中的值作为键名,该键值是在数组中出现的次数

因为要在后台显示,最好还是给它一个键名,循环一下

$info = [];
foreach ($invNums as $key => $value) {
    $info[]=['user_id'=>$key,'nums'=>$value];
}

ok,转成了二维关联数组,下一步操作:渲染到后台页面,分页

这就体现Yii的方便了,数据提供者类,之前都是从数据库查询数据并且以数组项的方式或者Active Record实例的方式返回,直接实例化ActiveDataProvider类就行了

结果我使用这个报错,The "query" property must be an instance of a class that implements the QueryInterface e.g. yii\db\Query or its subclasses.

意思是query属性必须是实现QueryInterface的类的实例,例如使用yii\db\Query或者yii\db\ActiveQuery,所以不能用这个去渲染数据到页面上

查看了一下手册,发现有一个 yii\data\ArrayDataProvider类,将一个大的数组依据分页和排序规格返回一部分数据

use yii\data\ArrayDataProvider;

$provider = new ArrayDataProvider([
    'allModels' => $info,
    'pagination' => [
        'pageSize' => 15,
    ],
    'sort' => [
        'attributes' => ['nums'],
    ],
]);

应该指定 allModels 属性作为一个大的数组, 这个大数组的元素既可以是一些关联数组也可以是一些对象,所以把我们的数组$info扔进去,同样的方式去刷新页面,ok,值有了

但是有个问题,数组数据提供者与Active Data ProviderSQL Data Provider这两者进行比较的话, 会发现数组数据提供者没有后面那两个高效,这是因为数组数据提供者需要加载所有的数据到内存中,2w条数据,在本地连接远程库,30s读取。推到测试服务器上,3s读取数据,还凑合,就先这样吧

参考资料

显示数据(Displaying Data): 数据提供器(Data Providers)- Yii Framework 中文网

发表评论

发表评论

*

沙发空缺中,还不快抢~