Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 重新排序CActiveDataProvider_Php_Sorting_Yii - Fatal编程技术网

Php 重新排序CActiveDataProvider

Php 重新排序CActiveDataProvider,php,sorting,yii,Php,Sorting,Yii,我正在寻找一种在Yii中重新排序CActiveDataProvider的方法 目前,我正在使用数据提供程序获取已排序和分页的数据 然后,我使用foreach循环来调整特定字段的数据,现在我需要根据新调整的数据对其重新排序 我无法使用afterFind对模型中的数据进行排序,因为我需要查询另一个DB(MySQL)来计算出一个计算值,而且它似乎不喜欢处理过程中的切换 我不想使用CArrayDataProvider,因为没有明显的方法对返回的数据进行分页,除非我在调整数据时将控件放入循环中,但是我不知

我正在寻找一种在Yii中重新排序CActiveDataProvider的方法

目前,我正在使用数据提供程序获取已排序和分页的数据

然后,我使用foreach循环来调整特定字段的数据,现在我需要根据新调整的数据对其重新排序

我无法使用afterFind对模型中的数据进行排序,因为我需要查询另一个DB(MySQL)来计算出一个计算值,而且它似乎不喜欢处理过程中的切换

我不想使用CArrayDataProvider,因为没有明显的方法对返回的数据进行分页,除非我在调整数据时将控件放入循环中,但是我不知道有多少数据可以返回,比如200条记录,但仅为显示调整20条似乎违反直觉

然后将这些内容推送到CGridView小部件

例如,现在我需要按升序重新调整下面的数组

$dataProvider = new CActiveDataProvider( blah );

foreach ( $dataProvider->getData() as $data ) {
 $data->Score += SomeModel::model()->findByPk(1)->NewScore;
}

array(
'Score' => 7
),
array(
'Score' => 6
)

$this->render('blah', array('data' => $dataProvider);

听起来您应该简单地实现一个新的
CDataProvider
,它封装了一个现有的
CDataProvider
。您将需要重写几个方法,但对于大多数方法,您只需转发到包装数据提供程序即可。代码可能会以如下方式结束:

$dataProvider = new CActiveDataProvider(...);
$myProvider = new CustomDataProvider($dataProvider);

// you could make CustomDataProvider work like this:
$myProvider->dataMutator = function(&$row, $key) {
    $row->Score = SomeModel::model()->findByPk(1)->NewScore;
};

$this->render('blah', array('data' => $myProvider);
protected function fetchData()
{
    $data = $this->wrappedProvider->fetchData();
    array_walk(&$data, $this->dataMutator);
    uasort($data, function($a, $b) { return $a->Score - $b->Score; });
    return $data;
}
CustomDataProvider::fetchData
可能如下所示:

$dataProvider = new CActiveDataProvider(...);
$myProvider = new CustomDataProvider($dataProvider);

// you could make CustomDataProvider work like this:
$myProvider->dataMutator = function(&$row, $key) {
    $row->Score = SomeModel::model()->findByPk(1)->NewScore;
};

$this->render('blah', array('data' => $myProvider);
protected function fetchData()
{
    $data = $this->wrappedProvider->fetchData();
    array_walk(&$data, $this->dataMutator);
    uasort($data, function($a, $b) { return $a->Score - $b->Score; });
    return $data;
}
我已经在这里硬连线了排序——这对于原型设计很有效,但是干净地指定后处理排序并不是一件小事,因为:

  • CDataProvider
    公开一个被忽略的
    sort
    属性。完全集成该属性将是一项非常重要的工作(您必须编写符合多个排序标准等的代码),或者更改
    CustomDataProvider.sort
    相对于其基类的
    sort
    的语义
    CDATA提供程序
    CSort
    结婚,因此,如果您想从OO的角度寻求最干净的解决方案,最好从头开始实施
    IDataProvider
  • 如果使用单个“sort
    属性,则
    CustomDataProvider
    的用户无法直观地了解排序的工作方式,因为
    sort`不能同时反映包装数据提供程序将执行的操作和“后处理”排序将执行的操作;然而,上述两项都将影响最终结果

我建议您使用一个原型,然后好好考虑一下对象模型应该是什么。

谢谢,但是我不确定数据在哪一点被引用,或者我应该如何在我的自定义提供程序中实现它,以便根据分数进行排序。@DamianCrawford:我对答案做了一些修改,看看它现在是否更有用。提醒:现在覆盖
fetchData
而不是
getData
。嗨@Jon,很抱歉在不同的评论中发表评论。我陷入了降序的困境,在没有分页的情况下,数据是以正确的降序来的。但是,一旦分页开始,数据就不会以正确的顺序出现。问题是-