返回首页 - Notes - 2018

PHP 模拟 SQL 多重 ORDER BY


代码实现

<?php

/*
 * 模拟 SQL 多重 ORDER BY,适用于任何有多重排序需求的二维数组
 * @params $_data array
 * @params $_sort array [['class2' => 'asc'], ['id' => 'asc'], ...]
 * @return array
 */
function array_multiple_order_by($_data, $_sort)
{
    foreach (array_keys($_sort) as $_n) {
        $$_n = [];
    }

    foreach ($_data as $_k => $_v) {
        foreach (array_keys($_sort) as $_n) {
            ${$_n}[$_k] = $_v[$_n];
        }
    }

    $_params = [];
    foreach ($_sort as $_n => $_s) {
        $_params[] = $$_n;
        $_params[] = ($_s == 'asc') ? SORT_ASC : SORT_DESC;
    }
    $_params[] = &$_data;

    call_user_func_array('array_multisort', $_params);

    return $_data;
}

调用示例

<?php

$data = [
    [
        'name' => '张三',
        'tag'  => 'x',
        'age'  => 18,
    ],
    [
        'name' => '李四',
        'tag'  => 'x',
        'age'  => 19,
    ],
    [
        'name' => '王五',
        'tag'  => 'y',
        'age'  => 20,
    ],
    [
        'name' => '张三2',
        'tag'  => 'z',
        'age'  => 21,
    ],
    [
        'name' => '李四2',
        'tag'  => 'y',
        'age'  => 22,
    ],
    [
        'name' => '王五2',
        'tag'  => 'x',
        'age'  => 23,
    ],
];

// 相当于 order by tag desc, age desc
$new_data = array_multiple_order_by($data, ['tag' => 'desc', 'age' => 'desc']);

排序结果:

Array
(
    [0] => Array
        (
            [name] => 张三2
            [tag] => z
            [age] => 21
        )
    [1] => Array
        (
            [name] => 李四2
            [tag] => y
            [age] => 22
        )
    [2] => Array
        (
            [name] => 王五
            [tag] => y
            [age] => 20
        )
    [3] => Array
        (
            [name] => 王五2
            [tag] => x
            [age] => 23
        )
    [4] => Array
        (
            [name] => 李四
            [tag] => x
            [age] => 19
        )
    [5] => Array
        (
            [name] => 张三
            [tag] => x
            [age] => 18
        )
)

date:2018-05-25