Signature
uasort(array &$array, callable $callback): truePurpose
uasort() sorts an array in place by its values, using a comparison function that you write. Unlike usort(), it keeps every key attached to its value. That makes it the right choice for associative arrays where the keys carry meaning, such as user IDs, product codes or player names, and you only want to change the order in which the entries appear.
Signature
Parameters and defaults
$arrayis the array to sort. It is passed by reference, so the original variable is rewritten. There is no copy to capture; if you need the original order afterwards, copy the array first.$callbackreceives two values from the array,$aand$b. It must return an integer that is less than zero, zero, or greater than zero when$ais considered respectively smaller than, equal to, or larger than$b.
Neither parameter has a default value. Both are required.
Return value and failure cases
Since PHP 8.2 the declared return type is true; before that it was bool. Either way the function always reports success, so checking the result is rarely useful. The sorted result lives in the array you passed in.
Passing something that is not an array, or something that is not callable, throws a TypeError. As of PHP 8.0, a callback that expects its parameters by reference triggers an E_WARNING. The function also resets the array's internal pointer to the first element.
Example 1: sorting scores while keeping names
The spaceship operator <=> is the simplest correct comparison for numbers and strings. The keys follow their values, and the return value is true.
$scores = ['ana' => 82, 'ben' => 95, 'cy' => 70, 'di' => 88];
$result = uasort($scores, fn(int $a, int $b): int => $a <=> $b);
echo json_encode($scores, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
var_dump($result);{"cy":70,"ana":82,"di":88,"ben":95}
bool(true)
Example 2: sorting records by a field
The callback can look inside nested values. Swapping the operands ($b first) gives a descending order. Entries that compare as equal keep their original relative order, so p1 stays ahead of p3.
$players = [
'p1' => ['name' => 'Ava', 'points' => 30],
'p2' => ['name' => 'Ben', 'points' => 45],
'p3' => ['name' => 'Cara', 'points' => 30],
'p4' => ['name' => 'Dev', 'points' => 50],
];
uasort($players, fn(array $a, array $b): int => $b['points'] <=> $a['points']);
echo json_encode(array_keys($players)), "\n";["p4","p2","p1","p3"]
Example 3: the float-return trap
The comparison result is converted to an integer. If you return a plain difference of floats, any fraction below one is truncated to 0, and those values are treated as equal. The first sort below leaves the order unchanged; the second, using <=>, sorts correctly.
$prices = ['a' => 1.5, 'b' => 1.2, 'c' => 1.9];
$wrong = $prices;
uasort($wrong, fn(float $x, float $y) => $x - $y);
$right = $prices;
uasort($right, fn(float $x, float $y): int => $x <=> $y);
echo json_encode($wrong), "\n";
echo json_encode($right), "\n";{"a":1.5,"b":1.2,"c":1.9}
{"b":1.2,"a":1.5,"c":1.9}
Edge cases
- Empty and single-element arrays are valid. The callback is never needed, and the function still returns
true. - Stable ordering: members that compare as equal keep their original order. Before PHP 8.0 their relative order was undefined, so older code might have added its own tie-breaker.
- Integer-like keys such as
"10"are stored as integers by PHP.uasort()never renumbers them, so they stay as they were. - Mixed types are handled by whatever your callback does. Using
<=>on mixed values follows PHP's normal comparison rules, which can surprise you, so compare like with like when you can. - Multiple criteria: chain comparisons with
?:or compare arrays, for example[$a['group'], $a['name']] <=> [$b['group'], $b['name']].
Common mistakes
- Expecting a return value to hold the sorted array. The function sorts the variable itself and returns
true. Writing$sorted = uasort($data, ...)gives you a boolean, not an array. - Returning a boolean or a float such as
$a > $bor$a - $b. Return an integer from<=>instead. - Using
usort()when keys matter.usort()discards the keys and assigns fresh numeric ones. Useuasort()to preserve them, oruksort()to sort by the keys. - Sorting by key by accident. The callback receives values, not keys. If the order depends on a key, use
uksort(), or restructure the data. - Forgetting the array is modified. Any other code relying on the earlier order will see the new order.
- Declaring callback parameters by reference. This emits a warning from PHP 8.0 onward. Take the values by value.
Related functions
usort()sorts by value with a custom comparison but does not preserve keys.uksort()sorts by key with a custom comparison.asort()andarsort()sort by value with standard comparison and keep keys.
Recap
uasort() sorts values with your own comparison function and keeps each key paired with its value. The array is changed in place, the return value is always true, equal items keep their original order, and the callback should return an integer, ideally from <=>.
Tested examples
$scores = ['ana' => 82, 'ben' => 95, 'cy' => 70, 'di' => 88];
$result = uasort($scores, fn(int $a, int $b): int => $a <=> $b);
echo json_encode($scores, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
var_dump($result);{"cy":70,"ana":82,"di":88,"ben":95}
bool(true)
$players = [
'p1' => ['name' => 'Ava', 'points' => 30],
'p2' => ['name' => 'Ben', 'points' => 45],
'p3' => ['name' => 'Cara', 'points' => 30],
'p4' => ['name' => 'Dev', 'points' => 50],
];
uasort($players, fn(array $a, array $b): int => $b['points'] <=> $a['points']);
echo json_encode(array_keys($players)), "\n";["p4","p2","p1","p3"]
$prices = ['a' => 1.5, 'b' => 1.2, 'c' => 1.9];
$wrong = $prices;
uasort($wrong, fn(float $x, float $y) => $x - $y);
$right = $prices;
uasort($right, fn(float $x, float $y): int => $x <=> $y);
echo json_encode($wrong), "\n";
echo json_encode($right), "\n";{"a":1.5,"b":1.2,"c":1.9}
{"b":1.2,"a":1.5,"c":1.9}