Yii通过继承ActiveController创建的api,如何处理排序

Yii中,通过继承ActiveController,我们可以很快的创建cuid的接口。
比如我们可以这样获取数据列表:
GET http://localhost:8080/articles
用GET方法对上面的url发起请求,就可以获取所有的数据的列表。
那么问题来了,如果我想排序,比如,按时间排序,按热度排序等等,那么在url中,关于排序的参数应该怎么传呢。

这个问题虽然看起来很简单,但是官方文档中好像并没有相关内容。

要知道答案,只有去看源码了

首先打开yii\rest\IndexAction
最后有这么一段代码

return Yii::createObject([
            'class' => ActiveDataProvider::className(),
            'query' => $query,
            'pagination' => [
                'params' => $requestParams,
            ],
            'sort' => [
                'params' => $requestParams,
            ],
        ]);

就是用来反回结果集的。
我们发现在createObject的参数中有sort这个属生,在这里,url的参数通过$requestParams这个变量给传了过来。而 $requestParams中和排序相关的参数会在ActiveDataProvider中进行匹配,最终生成排序规则。
我们可以猜想,ActiveDataProvider中肯定有一个setSort的方法,用来传这里面的sort的值。

所以我们现在要看一看ActiveDataProvider的源码。
果然,被我们找到

public function setSort($value)
    {

        if (is_array($value)) {
            $config = ['class' => Sort::className()];
            if ($this->id !== null) {
                $config['sortParam'] = $this->id . '-sort';
            }
          //  print_r($config);
            //print_r($value);
            $this->_sort = Yii::createObject(array_merge($config, $value));
        } elseif ($value instanceof Sort || $value === false) {
            $this->_sort = $value;
        } else {
            throw new InvalidArgumentException('Only Sort instance, configuration array or false is allowed.');
        }
    }

这里面的$value,就是我们从url中获取的参数。在这个方法中,创建了一个Yii\data\Sort的对象。
然后,ActiveDataProvider会通过Yii\data\Sort对象提供的相关方法来获取排序规则
打开Yii\data\Sort.php,我们可以看到这个方法

    public function getAttributeOrders($recalculate = false)
    {

        if ($this->_attributeOrders === null || $recalculate) {
            $this->_attributeOrders = [];
            if (($params = $this->params) === null) {
                $request = Yii::$app->getRequest();
                $params = $request instanceof Request ? $request->getQueryParams() : [];
            }
            if (isset($params[$this->sortParam])) {
                //print_r($this->attributes);
              //  print_r($this->parseSortParam($params[$this->sortParam]));
                foreach ($this->parseSortParam($params[$this->sortParam]) as $attribute) {
                    //echo $attribute;
                    $descending = false;
                    if (strncmp($attribute, '-', 1) === 0) {
                        $descending = true;
                        $attribute = substr($attribute, 1);
                    }

                    if (isset($this->attributes[$attribute])) {
                       // echo $attribute;
                        $this->_attributeOrders[$attribute] = $descending ? SORT_DESC : SORT_ASC;
                        if (!$this->enableMultiSort) {
                            return $this->_attributeOrders;
                        }
                    }
                }
            }
            if (empty($this->_attributeOrders) && is_array($this->defaultOrder)) {
                $this->_attributeOrders = $this->defaultOrder;
            }
        }

        return $this->_attributeOrders;
    }

这个方法干的事就是把url中获取的排序相关的参数转化程具体的排序规则返回,然后再ActiveDataProvider中通过这句代码

$query->addOrderBy($sort->getOrders());

来把排序添加到查询中。

在上面Sort代码中有这段

foreach ($this->parseSortParam($params[$this->sortParam]) as $attribute)
{
、、、、、、、、、
}

因为$this->sortParam=“sort",
parseSortParam方法是对url中的排序参数进行解析,
找到parseSortParam方法代码

 /**
     * Parses the value of [[sortParam]] into an array of sort attributes.
     *
     * The format must be the attribute name only for ascending
     * or the attribute name prefixed with `-` for descending.
     *
     * For example the following return value will result in ascending sort by
     * `category` and descending sort by `created_at`:
     *
     * ```php
     * [
     *     'category',
     *     '-created_at'
     * ]
     * ```
     *
     * @param string $param the value of the [[sortParam]].
     * @return array the valid sort attributes.
     * @since 2.0.12
     * @see $separator for the attribute name separator.
     * @see $sortParam
     */
    protected function parseSortParam($param)
    {
        return is_scalar($param) ? explode($this->separator, $param) : [];
    }

从注释可以看出,这个方法的返回值是一个数组,格式是这样的
[‘category’,’-created_at’]

 return is_scalar($param) ? explode($this->separator, $param) : [];

这段代码实现的功能是,如果$param不是数组,将把它按逗号拆分成数组返回,否则返回空数组,
所以url中正确的参数规则应该是逗号分隔的字符串,就你这样
xxx=create_at,category
那么这个xxx应该是什么呢,是 $this->sortParam的值,也就是”sort"

所以,我们想要实现排序,应该这样

GET http://localhost:8080/users?sort=-create_at,category
字段前面什么都没就,就是正序,字段前加一个“-”,就是倒序。

然而,有一点需要注意,如果我们需要进行多个字段的排序的话,需要让Sort类中的$enableMultiSort属性为true,而默认是false。
所以我们需要在IndexAction中,传这样一个参数 ‘enableMultiSort’=>true,

    return Yii::createObject([
            'class' => ActiveDataProvider::className(),
            'query' => $query,
            'pagination' => [
                'params' => $requestParams,
      
            ],
            'sort' => [
               'params' => $requestParams,
               'enableMultiSort'=>true,
          
            ],
        ]);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Yii2框架的Active Record是一个强大的ORM(对象关系映射)工具,它可以将数据库中的表映射成为Yii2框架中的PHP类,并且提供了一系列的API来进行对数据库的操作。 下面是一些常用的Active Record操作: 1. 查询单条记录: ```php $model = ModelName::findOne($id); ``` 2. 查询多条记录: ```php $models = ModelName::find()->where(['attribute' => 'value'])->all(); ``` 3. 插入记录: ```php $model = new ModelName(); $model->attribute = 'value'; $model->save(); ``` 4. 更新记录: ```php $model = ModelName::findOne($id); $model->attribute = 'new value'; $model->save(); ``` 5. 删除记录: ```php $model = ModelName::findOne($id); $model->delete(); ``` 6. 自定义查询: ```php $models = ModelName::find()->select(['attribute1', 'attribute2'])->asArray()->all(); ``` 上述代码中,`ModelName`是你定义的Active Record类名,`findOne()`方法用于查找单条记录,`find()`方法用于查找多条记录,`where()`方法用于设置查询条件,`all()`方法返回所有查询结果,`new`关键字用于创建新的Active Record实例,`save()`方法用于保存数据到数据库中,`delete()`方法用于删除数据,`select()`方法用于指定查询的列,`asArray()`方法用于返回查询结果数组而不是Active Record对象。 需要注意的是,Active Record还提供了一些高级的操作,如关联查询、批量操作、查询缓存等。详细的信息可以参考Yii2官方文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值