phpsortingmultidimensional-arrayusort

Why do I need multiple iterations with php usort?


I scrape users from a database and save it into an array (there are about 1500 users). Then I want to sort them based on the array field "flags". It is an integer between 1 and 99 and multiple users can have the same value. So the array and the sorting may look like this:

$Users = array(
    0 => array(
        'name' => 'John Doe',
        'email' => 'john@example.com',
        'flags' => '36'
    ),
    1 => array(
        'name' => 'Jane Doe',
        'email' => 'jane@example.com',
        'flags' => '35'
    ),
);;

usort($Users, "sort_flags");

This is my callback function for usort:

function sort_flags($a, $b) {
    if (isset($a['flags']) and isset($b['flags'])) {
        $flag_compare_result = $a['flags'] <=> $b['flags'];     
    }   
    return $flag_compare_result ?? "";
}

I execute the usort statement one time and I get a result like this (with more numbers, but this is a piece of it): 10, 35, 36, 36, 36, 36, 36, 37, 37, 38, 35, 36, 37, 37, 38, 38, 39, 39, 39, 40, 41, 42...

But if I execute the usort statement a second time, I get the expected result: 10, 35, 35, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 39, 39, 39, 40, 41, 42...

I don't know exactly what to ask, maybe my code is wrong, maybe I am missing some key concept of this function. Is the array I try to sort too big? When yes, is there a limit size for a maximally randomized array?


Solution

    1. Compare the values as integers, not strings.
    2. Instead of providing a default comparison result when either flags isn't set, provide a default value for the flags. This ensures you get a consistent total ordering.
    function sort_flags($a, $b) {
        return intval($a['flags'] ?? 0) <=> intval($b['flags'] ?? 0);     
    }