uksort
Sorts an array by its keys using a custom comparison callback, keeping values attached.
uksort(array &$array, callable $callback): true- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$array | array | The array to sort. Passed by reference; each value stays attached to its key. |
$callback | callable | Comparison function callback(mixed $a, mixed $b): int receiving two keys. Must return an integer less than, equal to, or greater than zero when $a is respectively less than, equal to, or greater than $b. |
Return value
trueAlways returns true. The array is sorted in place through the reference.
Errors
Nothing is thrown by uksort itself, but any Throwable raised inside the callback propagates and aborts the sort. A callback that is not callable raises a TypeError.
Changelog
- PHP 8.2The return type is true now; previously it was bool.
- PHP 8.0If the callback expects a parameter to be passed by reference, an E_WARNING is emitted.
See also
uksort orders an array by its keys using rules you write. The callback receives two keys — never the values — and returns a negative number, zero, or a positive number. Values follow their keys into the new order.
When to reach for it
Use it when key order matters and the natural comparison is wrong. Common cases: sorting keys like chapter2, chapter10 in human order with strnatcmp; sorting version-string keys with version_compare; ignoring a prefix or article, as in filing "the Earth" under E; or imposing a fixed business order such as ['critical', 'high', 'low'] by comparing each key's position in a lookup array.
What trips people up
Array keys are already normalised before your callback ever runs. A key written as '10' is stored as the integer 10, and true becomes 1, so a callback expecting strings may receive integers — strnatcmp on an integer key works only because PHP coerces it. Cast explicitly with (string) if your comparison depends on string behaviour.
As with the other user sorts, return an integer, not a boolean, and never a truncated float subtraction. And remember the callback runs O(n log n) times, so keep anything expensive — a regex, a date parse — out of it by precomputing when the array is large.
Example
When to use it
- Sort section keys like 'part2', 'part10' in natural reading order with strnatcmp.
- Order version-numbered keys such as '1.9' and '1.10' using version_compare.
- Impose a fixed priority order (critical, high, low) on a status-keyed summary array.
Frequently asked questions
What is the difference between uksort and uasort?
uksort passes the array keys to your callback; uasort passes the values. Both keep key/value pairs intact, so pick the one matching what you want to compare.
Can I access the array values inside a uksort callback?
Not through the parameters, which are keys only. Capture the array by value in a closure (use ($arr) or an arrow function) and look values up by key inside the callback.
Why does my uksort callback receive integers instead of strings?
PHP normalises array keys on insertion, so a key written as '10' is stored as the integer 10. Cast with (string) inside the callback if your comparison needs string semantics.
More examples
A fixed business ordering
The lookup array turns each key into a rank, so the output is critical 3, high 12, low 41 — an order no built-in sort flag could produce, since alphabetically 'critical' < 'high' < 'low' only works here by coincidence and would break for other labels.
<?php
$order = ['critical' => 0, 'high' => 1, 'low' => 2];
$counts = ['low' => 41, 'critical' => 3, 'high' => 12];
uksort($counts, fn($a, $b) => $order[$a] <=> $order[$b]);
foreach ($counts as $level => $n) {
echo str_pad($level, 9), $n, "\n";
}Version keys and key coercion
version_compare gives 1.2 1.9 1.10, the correct release order. The second block prints 'integer' from inside the callback, showing that the numeric-looking keys '10' and '9' were stored as ints before uksort ever saw them.
<?php
$releases = ['1.9' => 'old', '1.10' => 'newer', '1.2' => 'older'];
uksort($releases, 'version_compare');
echo implode(' ', array_keys($releases)), "\n";
$mixed = ['10' => 'a', '9' => 'b'];
uksort($mixed, function ($a, $b) {
echo gettype($a), ' ';
return $a <=> $b;
});
echo "\n", implode(',', array_keys($mixed)), "\n";
Discussion