In PHP, what is the difference between sort(), asort() and ksort(), and which of them keep an array's keys?
answer
- values or keys, kept or dropped
- sort renumbers from 0
- a prefix keeps the pairing
- k prefix orders by key
- in place, returns true
basics
~10 ssort() orders the values and renumbers the keys 0, 1, 2; asort() orders the values but keeps each key with its value; ksort() orders by key. All three sort in place and return true.
solid answer
~40 sAll PHP sort functions work **in place** on the array you pass and return `true`, not a sorted copy. `sort()` orders by value and throws the keys away, renumbering them `0, 1, 2`. `asort()` also orders by value but keeps every key attached to its value, which is what you want for an associative array such as `['p17' => 820]`. `ksort()` orders by the keys themselves and keeps the pairs too. Each has a descending twin: `rsort()`, `arsort()` and `krsort()`, with the same key behaviour. So to rank a leaderboard keyed by player id you call `arsort($scores)`; calling `rsort()` there would leave you with scores and no idea whose they are.
code
php · 18 lines<?php
declare(strict_types=1);
$scores = ['p17' => 820, 'p03' => 950, 'p42' => 820, 'p08' => 610];
$ranked = $scores;
arsort($ranked);
print_r($ranked); // [p03 => 950, p17 => 820, p42 => 820, p08 => 610]
$lost = $scores;
rsort($lost);
print_r($lost); // [0 => 950, 1 => 820, 2 => 820, 3 => 610]
$byId = $scores;
ksort($byId);
print_r($byId); // [p03 => 950, p08 => 610, p17 => 820, p42 => 820]
var_dump(sort($lost)); // bool(true), not an arraygo deeper
Recall the naming rule: no prefix drops keys, a keeps the key-value pairing, k sorts by key, r reverses. Know that every sort changes the variable in place and returns true.
Explain why sort() on an associative array is a silent bug, how to sort a copy without touching the original, and how the callback forms follow the same keep-or-drop split.
Spot key loss in review: a sort() on an id-keyed map, or code that assigns the return value of a sort. Pick the function from what the keys mean, not from habit.
Treat key-preserving sorts as part of a data contract: once an array's keys are identifiers, every transformation in the pipeline must keep them, and reviews should check each step for it.
## Two questions every PHP sort answers A PHP array is an ordered map: every element has a **key** (an `int` or a `string`) and a **value**, and the array remembers the order in which the pairs sit. Sorting changes that order. Each built-in sort function answers two questions: 1. **What is compared** — the values or the keys? 2. **What happens to the keys** — are they kept with their values, or thrown away and replaced by `0, 1, 2, …`? The function name encodes both answers. A leading `a` means *association kept* (sort by value, keep the keys). A leading `k` means *sort by key* (and keep the pairs). No prefix means *sort by value and renumber*. An `r` after the prefix means *reverse*, i.e. descending. ## The six basic functions | Function | Compares | Keys after the sort | Direction | |---|---|---|---| | `sort()` | values | renumbered `0..n-1` | ascending | | `rsort()` | values | renumbered `0..n-1` | descending | | `asort()` | values | kept with their values | ascending | | `arsort()` | values | kept with their values | descending | | `ksort()` | keys | kept with their values | ascending | | `krsort()` | keys | kept with their values | descending | The same split runs through the callback versions: `usort()` drops keys, `uasort()` keeps them, `uksort()` compares keys. ## A leaderboard keyed by player id Suppose a quiz game stores results as `['p17' => 820, 'p03' => 950, 'p42' => 820, 'p08' => 610]`, player id to score. - `arsort($scores)` gives `['p03' => 950, 'p17' => 820, 'p42' => 820, 'p08' => 610]`: highest score first, every id still attached. This is the ranking you want. - `rsort($scores)` gives `[0 => 950, 1 => 820, 2 => 820, 3 => 610]`: the scores are in the right order, but the player ids are gone for good. - `ksort($scores)` gives the players ordered by id (`p03`, `p08`, `p17`, `p42`), which is useful for a stable admin listing but says nothing about rank. The mistake interviewers look for is using `sort()` or `rsort()` on an associative array and silently losing the keys. Nothing warns you: the function succeeds, and the damage only shows when some later code looks up `$scores['p17']` and finds nothing. ## In place, and the return value is just `true` Every one of these functions takes the array **by reference** and reorders that variable. None of them returns the sorted array. Their return value is always `true`, so this common slip: ```php $ranked = arsort($scores); // $ranked is true, $scores is sorted ``` leaves `$ranked` holding a boolean. Two consequences follow: - Pass a variable. Handing a sort the direct result of a function call makes PHP raise a notice and sort a temporary copy that you can never read back. - If you need both the original order and a sorted order, copy first: `$ranked = $scores; arsort($ranked);`. Assigning an array to another variable copies it by value, so sorting `$ranked` leaves `$scores` as it was. ## Why losing keys is easy to miss A list and a map print almost the same; only the keys differ. After an accidental `rsort()`, a loop such as `foreach ($scores as $id => $score)` still runs without any error, but `$id` now holds `0`, `1`, `2`, so the page shows player 0 instead of `p03`. Tests that check only the values or the count keep passing. A useful review question is: *what do the keys of this array mean?* If the answer is anything other than "position", the sort has to be one that keeps them: `asort()`, `arsort()`, `ksort()`, `krsort()`, or the callback forms `uasort()` and `uksort()`. ## Choosing the right function - The array is a plain list (`[820, 950, 610]`) and positions carry no meaning: `sort()` or `rsort()`. - The keys are identifiers (player ids, SKUs, usernames) and you order by the values: `asort()` or `arsort()`. - You want the entries ordered by the identifiers themselves: `ksort()` or `krsort()`. - The order depends on something more complex than one scalar (score, then time): the callback forms, with the same keep-or-drop rule. Each of the six also accepts an optional `$flags` argument (default `SORT_REGULAR`) that changes *how* two values are compared, for example as strings or in natural order; that choice is separate from the keep-or-drop choice made by the function name.
- How do you get a sorted version of an array while keeping the original order too?Copy it into a second variable and sort the copy: `$ranked = $scores; arsort($ranked);`. PHP arrays are values, so the assignment gives `$ranked` its own array and sorting it does not touch `$scores`. Wrapping the same two lines in a small function that takes the array by value and returns it gives you an expression-style helper.
- Is there a descending version of usort(), and how do you sort descending with a callback?No. The `r` twins exist only for the six flag-based functions. With `usort()`, `uasort()` or `uksort()` you get descending order by swapping the operands in the comparator, for example `fn($a, $b) => $b <=> $a`, so the comparator itself decides the direction.
saying these in an interview costs you the question
- sort() returns the sorted array, so $sorted = sort($a) works
- asort() sorts an array by its keys
- rsort() keeps the keys and only reverses the order
- ksort() renumbers the keys after sorting
- PHP sort functions leave the original array untouched