Yii数据提供程序日期排序


Yii Dataprovider date sorting

我有一个字段类型为DateTime-birthdate的ArrayDataProvider。我将该数据提供程序用于视图中的网格视图部分。

由于出生日期包括出生年份,因此排序无法按预期进行。有没有办法告诉排序机制不要计算年份,只按月份和日期排序也许是自定义排序函数?

编辑:类似于C++中的sort,您可以在其中传递比较函数。

编辑的当前解决方案描述:我目前的解决方案是将出生年份作为一个单独的字段包含在数组中,并且将出生日期的年份设置为当前年份。现在日期是同一年的,排序工作正常。但是,把出生年份单独列出来是不对的。我希望我能从一个日期对象中获得所有必要的数据。

这片独立的土地磨磨着我的齿轮。这并不完美。

编辑:哦,还有它的Yii2

更新还有一个PHP数组排序函数可以进行比较回调,例如uasort,它可以用于关联数组,如我的:

uasort($persons, function($a, $b){
    return strcasecmp( $b['date']->format('m-d'), $a['date']->format('m-d') );
});

现在我需要找到将其实现到ArrayDataProvider中的方法。有什么想法吗?

如果您有一个数组数据提供程序,那么您当然不能使用数据库排序。

使用Yii的解决方案

要允许按某个表达式排序,您必须预先计算值,并配置属性的排序以使用计算值而不是原始值:

// assuming $data contains your data and 'birthdate' is the value you want to use for sorting
foreach($data as $key => $value) {
    $data[$key]['sort_birthdate'] = date('m-d', strtotime($value['birthdate']));
}
$dataProvider = new 'yii'data'ArrayDataProvider([
    'allModels' => $data,
    'sort' => [
        'attributes' => [
            'birthdate' => [
                'asc' => [
                    'sort_birthdate' => SORT_ASC, 
                ],
                'desc' => [
                    'sort_birthdate' => SORT_DESC, 
                ],
                'label' => 'Date',
                'default' => SORT_ASC
            ],
            // list all other attributes here
        ],
    ]
]);

扩展Yii的解决方案

如果你想要一个自定义的比较函数,你必须扩展Yii类来支持它。您可以创建一个自定义ArrayDataProvider类,该类从Yii附带的类扩展而来,并覆盖sortModels()-方法。

您应该尝试类似的东西

use yii'db'Expression;
$dataProvider->setSort([
            'attributes' => [
................................
                'birthday' => [
                    'asc' => [
                        new Expression('DATE_FORMAT(birthday, "%m%d")') => SORT_ASC, 
                    ],
                    'desc' => [
                        new Expression('DATE_FORMAT(birthday, "%m%d")') => SORT_DESC, 
                    ],
                    'label' => 'Birthday',
                    'default' => SORT_ASC
                ],
................................
            ]
        ]);

我没有试过这个。

可以肯定的是,做一些类似的事情

$query->select([
                    new Expression('DATE_FORMAT(birthday, "%m%d") as show_date'), 
      .................................
                ]);

然后

    /**
     * Setup your sorting attributes
     * Note: This is setup before the $this->load($params) 
     * statement below
     */
     $dataProvider->setSort([
        'attributes' => [
            'id',
            'show_date' => [
                'asc' => [
                    'sort_date' => SORT_ASC, 
                ],
                'desc' => [
                    'sort_date' => SORT_DESC, 
                ],
                'label' => 'Date',
                'default' => SORT_ASC
            ],
            'price',
            'gst',
            'cost',
            'quantity',
            'profit',
        ]
    ]);