Arrays7 min readExamples run on PHP 8.5.10

ksort()

Learn how PHP 8.4 ksort() sorts an array in place by its keys, how the flags change comparison, and which mistakes to avoid.

Signature

ksort(array &$array, int $flags = SORT_REGULAR): true

Purpose

ksort() rearranges an array so that its keys run in ascending order. Each key keeps the value it was paired with; only the order of the pairs changes. Use it when the keys carry meaning, such as product codes, IDs or labels, and you want to iterate or output them in key order. If you want to order by value instead, look at asort() or sort().

The function works in place. It changes the variable you pass in and does not hand back a sorted copy.

Signature

Parameters and defaults

  • $array is taken by reference, so you must pass a variable. A literal array or a function call result cannot be sorted this way.
  • $flags controls how keys are compared. The default is SORT_REGULAR, which uses PHP's normal comparison rules.

The available flags are:

  • SORT_REGULAR: compare keys normally.
  • SORT_NUMERIC: compare keys as numbers.
  • SORT_STRING: compare keys as strings.
  • SORT_LOCALE_STRING: compare as strings using the current locale. This depends on the environment, so avoid it where you need predictable results.
  • SORT_NATURAL: compare as strings using natural ordering, like natsort().
  • SORT_FLAG_CASE: combine it with SORT_STRING or SORT_NATURAL using | to ignore letter case.

Return value and failure cases

Since PHP 8.2 the declared return type is true, and the function always returns true. Earlier versions declared bool. There is no failure value to check, so the return value is rarely useful. The real result is the changed array.

If two keys compare as equal, their original relative order is kept. The manual notes that this was undefined before PHP 8.0. ksort() also resets the array's internal pointer to the first element.

Example 1: basic string keys

The array below is sorted alphabetically by key. The values travel with their keys. The var_dump() call shows that the return value is just true.

Example
<?php
$stock = ["pear" => 4, "apple" => 10, "mango" => 7];
$result = ksort($stock);
echo json_encode($stock, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
var_dump($result);
Output
{"apple":10,"mango":7,"pear":4}
bool(true)

Example 2: numeric keys and SORT_STRING

With integer keys, the default comparison is numeric, so 2 comes before 10. Forcing SORT_STRING compares the keys as text, so "10" comes before "2". The two calls work on separate copies so the results can be compared.

Example
<?php
$ids = [10 => "ten", 9 => "nine", 2 => "two"];
$regular = $ids;
$text = $ids;
ksort($regular);
ksort($text, SORT_STRING);
echo json_encode($regular, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode($text, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"2":"two","9":"nine","10":"ten"}
{"10":"ten","2":"two","9":"nine"}

Example 3: natural, case-insensitive order

A default sort compares non-numeric strings byte by byte, so uppercase letters come before lowercase ones and img12 comes before img2. Combining SORT_NATURAL with SORT_FLAG_CASE gives the order people usually expect for names with numbers in them.

Example
<?php
$files = ["img12" => "c", "IMG2" => "b", "img1" => "a"];
$default = $files;
$natural = $files;
ksort($default);
ksort($natural, SORT_NATURAL | SORT_FLAG_CASE);
echo json_encode($default, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode($natural, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"IMG2":"b","img1":"a","img12":"c"}
{"img1":"a","IMG2":"b","img12":"c"}

Edge cases

  • Empty and single-element arrays are accepted and left unchanged.
  • Numeric-string keys such as "10" are stored by PHP as integer keys, so they behave as numbers under the default flag.
  • Mixed integer and string keys follow the general comparison rules, which can surprise you. If the key types are mixed, choose an explicit flag such as SORT_STRING so the order is easy to predict.
  • Lists lose their meaning of order. After sorting, the array keeps its original keys. A list that was [0, 1, 2] by position may end up with keys in a different order. Use array_values() if you need a fresh zero-based list.
  • Locale-based sorting with SORT_LOCALE_STRING can differ between machines, so it is not suitable for reproducible output.

Common mistakes

  1. Assigning the result. Writing $sorted = ksort($data); stores true, not an array. Call ksort($data); and then use $data.
  2. Passing a non-variable. Because the parameter is by reference, ksort(getData()) is an error. Store the array in a variable first.
  3. Expecting value order. ksort() ignores values completely. Use asort() to sort by value while keeping keys.
  4. Forgetting the original. The original order is gone once you sort. Copy the array first if you need both.
  5. Assuming case-insensitive order. Without SORT_FLAG_CASE, uppercase keys sort before lowercase keys under byte comparison.
  6. Wanting descending order. ksort() only sorts ascending. Use krsort() for the reverse.
  • krsort() sorts by key in descending order.
  • sort() sorts values in ascending order and reindexes the array.
  • asort() sorts by value and keeps the key association.
  • uksort() sorts by key with your own comparison callback.
  • natsort() applies natural ordering to values.

Recap

ksort() sorts an array in place by key, ascending, and always returns true. Pick the flag that matches how your keys should be compared, such as SORT_STRING for text order or SORT_NATURAL | SORT_FLAG_CASE for names with embedded numbers. Remember that it takes a variable by reference, keeps each value with its key, and keeps the original order for keys that compare as equal.

Tested examples

Sort string keys and inspect the return value
<?php
$stock = ["pear" => 4, "apple" => 10, "mango" => 7];
$result = ksort($stock);
echo json_encode($stock, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
var_dump($result);
Output
{"apple":10,"mango":7,"pear":4}
bool(true)
Numeric keys compared numerically and as strings
<?php
$ids = [10 => "ten", 9 => "nine", 2 => "two"];
$regular = $ids;
$text = $ids;
ksort($regular);
ksort($text, SORT_STRING);
echo json_encode($regular, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode($text, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"2":"two","9":"nine","10":"ten"}
{"10":"ten","2":"two","9":"nine"}
Natural, case-insensitive key order
<?php
$files = ["img12" => "c", "IMG2" => "b", "img1" => "a"];
$default = $files;
$natural = $files;
ksort($default);
ksort($natural, SORT_NATURAL | SORT_FLAG_CASE);
echo json_encode($default, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode($natural, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"IMG2":"b","img1":"a","img12":"c"}
{"img1":"a","IMG2":"b","img12":"c"}