Scroll to top

It's always easier to grab a specific piece of information from sorted data, otherwise you have to go through each element of the array one at a time.

For example, let's say you've stored the score of different students in a class in an array or a table. If the data is not sorted by the scores obtained, you'll have to look at the score of each student in the class before you can tell who obtained the highest and lowest score. If the table was already sorted low to high on basis of scores, just looking at the score of the first student would tell you the lowest mark.

Sorting makes a lot of tasks that require accessing or obtaining a specific set of data very easy and efficient. In this tutorial, we will learn how to use built-in PHP functions to sort different kinds of array.

Sorting an Array by Value

Sorting an array by the value of its elements is very easy in PHP. You can choose to maintain or discard key-value associations, and you can also define your own functions to dictate how elements are sorted. I'll show you how in this section of the tutorial.

You can use the sort(&$array, $sort_flags) function to sort the values of an array from low to high. However, it will not maintain any key-value associations when sorting the array. New keys are assigned to sorted elements instead of a simple reordering. The optional second parameter allows you to specify how the elements should be sorted. It can have six different values:

  1. SORT_REGULAR—sort the values without changing their types.
  2. SORT_NUMERIC—sort the values by comparing them numerically.
  3. SORT_STRING—sort the values by comparing them as strings.
  4. SORT_LOCALE_STRING—compare the values as strings based on the current locale. You can update the locale yourself by using setlocale().
  5. SORT_NATURAL—sort the items using "natural ordering" while comparing them as strings.
  6. SORT_FLAG_CASE—can be combined with SORT_STRING or SORT_NATURAL to turn off case-sensitivity while sorting strings.

Here are a couple of sorting examples to help you quickly grasp the difference between all the sort flags.

1
<?php
2
3
$random_data = [32508, 98134, "234984", "3249832", "38", 123, "Apple"];
4
5
sort($random_data);
6
echo "Regular Sorting  — ";
7
foreach($random_data as $element) {
8
    echo str_pad($element, 9)." ";
9
}
10
// Regular Sorting  — 38        123       32508     98134     234984    3249832   Apple

11
12
sort($random_data, SORT_NUMERIC);
13
echo "\nNumeric Sorting  — ";
14
foreach($random_data as $element) {
15
    echo str_pad($element, 9)." ";
16
}
17
// Numeric Sorting  — Apple     38        123       32508     98134     234984    3249832

18
19
sort($random_data, SORT_STRING);
20
echo "\nString Sorting   — ";
21
foreach($random_data as $element) {
22
    echo str_pad($element, 9)." ";
23
}
24
// String Sorting   — 123       234984    3249832   32508     38        98134     Apple

In the first example, regular sorting, the numerical strings are converted to their numerical values, and sorting is done accordingly. The "Apple" string is non-numeric, so it is left untouched and compared as a string.

In the second example, numeric sorting, we want the data to be sorted based on numerical value, so "Apple" is converted to the numeric value 0 and comes first. The rest of the values are sorted as expected.

In the third example, all the values are treated as strings. This means that instead of comparing the numerical value of 123 or 3249832 with 38, they are compared as strings—one character at a time. Since "1" comes before "3", the value 123 is considered lower than 38.

If you want to sort your array values from high to low instead of low to high, you can do so with the help of the rsort() function. It accepts all the same parameters as sort() but sorts the values in reverse order. It also doesn't maintain any key-value associations, so it isn't a good pick for sorting associative arrays.

Sort an Associative Array

Key-value associations become important when you are dealing with associative arrays.

Consider the following example, where an associative array is used to store the names of different persons and their favorite fruit. If you want to sort the list alphabetically by the names of the fruit, using the sort() function from the previous section will result in the loss of the associated keys.

1
<?php
2
3
$fruit_preferences = ["James" => "Orange", "John" => "Banana", "Patricia" => "Apple", "Jennifer" => "Mango", "Mary" => "Grapes"];
4
5
echo "Before Sorting — \n";
6
foreach($fruit_preferences as $person=>$preference) {
7
    echo $person." likes ".$preference."\n";
8
}
9
10
/*

11
Before Sorting — 

12
James likes Orange

13
John likes Banana

14
Patricia likes Apple

15
Jennifer likes Mango

16
Mary likes Grapes

17
*/
18
19
sort($fruit_preferences);
20
21
echo "After Sorting  — \n";
22
foreach($fruit_preferences as $person=>$preference) {
23
    echo $person." likes ".$preference."\n";
24
}
25
26
/*

27
After Sorting  — 

28
0 likes Apple

29
1 likes Banana

30
2 likes Grapes

31
3 likes Mango

32
4 likes Orange

33
*/
34
35
?>

As you can see, we not only lost the association of people with their favorite fruit, but we also lost the names of the different people. Each sorted value has been assigned a new numeric index based on its position in the sorted array.

To help you tackle this problem easily, PHP has two different functions which maintain key-value association while sorting arrays by their values. These two functions are asort() and arsort(). The following code snippet sorts the same $fruit_preferences array but uses asort() to do so.

1
<?php
2
3
$fruit_preferences = ["James" => "Orange", "John" => "Banana", "Patricia" => "Apple", "Jennifer" => "Mango", "Mary" => "Grapes"];
4
5
echo "Before Sorting — \n";
6
foreach($fruit_preferences as $person=>$preference) {
7
    echo $person." likes ".$preference."\n";
8
}
9
10
/*

11
Before Sorting — 

12
James likes Orange

13
John likes Banana

14
Patricia likes Apple

15
Jennifer likes Mango

16
Mary likes Grapes

17
*/
18
19
asort($fruit_preferences);
20
21
echo "After Sorting  — \n";
22
foreach($fruit_preferences as $person=>$preference) {
23
    echo $person." likes ".$preference."\n";
24
}
25
26
/*

27
After Sorting  — 

28
Patricia likes Apple

29
John likes Banana

30
Mary likes Grapes

31
Jennifer likes Mango

32
James likes Orange

33
*/
34
35
?>

As is evident from the above example, the value Apple moves to the top while still maintaining its association with Patricia. The fruit names could be sorted in reverse just as easily by using the arsort() function.

Both these functions accept the same sorting flags as the value of their optional second parameter as sort() and rsort().

Sorting Array Elements by Value With User-Defined Functions

The four sorting functions can easily handle your common sorting needs with the help of different flags. However, sometimes your criteria for comparing the array elements might be different.

Let's say you have an array of random words which need to be sorted alphabetically. However, you also want to sort them based on their length before sorting them alphabetically. For example, zoo would come after apple in traditional alphabetical sorting. However, if you want to show the short words before longer ones, zoo will appear before apple. In the same set of letters, ape would come before zoo due to alphabetical ordering.

Basically, the words are first sorted based on their length, and then the words with the same number of letters are sorted alphabetically within their own group. This type of sorting is not built into PHP, so we will have to write our own sorting function.

What PHP does in this case is provide you with a couple of functions which can be used to pass the array that you want to sort, along with the name of your own sorting function.

You can use the usort() function to sort array values in regular arrays. Similarly, you can use the uasort() function to sort values in associative arrays while also maintaining key-value associations.

The code snippet below shows one way of accomplishing this behavior.

1
<?php
2
3
$random_words = ["ape", "apple", "zoo", "pie", "elephant", "banana", "picnic", "eye"];
4
5
sort($random_words);
6
echo "Regular Sort Function: \n";
7
foreach($random_words as $element) {
8
    echo str_pad($element, 9)." ";
9
}
10
11
/*

12
Regular Sort Function: 

13
ape       apple     banana    elephant  eye       picnic    pie       zoo

14
*/
15
16
function custom_sort($word_a, $word_b) {
17
    if (strlen($word_a) < strlen($word_b)) {
18
        return -1;
19
    }
20
    if (strlen($word_a) == strlen($word_b)) {
21
        return strcmp($word_a, $word_b);
22
    }
23
    if (strlen($word_a) > strlen($word_b)) {
24
        return 1;
25
    }
26
}
27
28
usort($random_words, "custom_sort");
29
echo "\nCustom Sort Function: \n";
30
foreach($random_words as $element) {
31
    echo str_pad($element, 9)." ";
32
}
33
34
/*

35
Custom Sort Function: 

36
ape       eye       pie       zoo       apple     banana    picnic    elephant

37
*/
38
39
?>

In the callback functions meant for custom sorting, we have to return an integer less than 0 to indicate that the first value is smaller than the second. Return 0 if the first value is equal to the second. Return an integer greater than 0 if the first value is greater than second.

Since our primary sorting criteria was string length, we directly return -1 if the first word is shorter than the second. Similarly, we directly return 1 if the first word is longer than the second. If the two words are equal in length, we compare them alphabetically using the strcmp() function and return its value.

As you can see in the output, our custom sort function reorders the words exactly the way we wanted.

Sorting an Array by Key

Sorting an array based on its keys is generally useful when you are dealing with associative arrays.

For instance, you might have an array with information about the total number of airports in various countries. Assuming that the names of different countries are keys and the numbers of airports are values, you might want to sort the country names alphabetically. This is very easy to do with the ksort() and krsort() functions. Both these functions will maintain the key-value association of array elements after sorting. The ksort() function sorts the keys from low to high, and krsort() sorts the keys from high to low.

Here is a basic sorting example:

1
<?php
2
3
$airport_count = ["United States" => 13513, "Brazil" => 4093, "Mexico" => 1714, "Canada" => 1467, "Russia" => 1218, "Argentina" => 1138, "Bolivia" => 855, "Colombia" => 836, "Paraguay" => 799, "Indonesia" => 673];
4
5
ksort($airport_count);
6
7
foreach($airport_count as $country=>$count) {
8
    echo str_pad($country, 15)." ".$count."\n";
9
}
10
11
/*

12
Argentina       1138

13
Bolivia         855

14
Brazil          4093

15
Canada          1467

16
Colombia        836

17
Indonesia       673

18
Mexico          1714

19
Paraguay        799

20
Russia          1218

21
United States   13513

22
*/
23
24
?>

You can also provide PHP with your own custom function for sorting array keys using the uksort() function. Just like usort(), the callback function in uksort() also requires you to return an integer less than 0 if the first key is considered less than the second one and an integer greater than 0 if the first key is greater than second. This function also maintains the key-value association of array elements.

1
<?php
2
3
$airport_count = ["United States" => 13513, "Brazil" => 4093, "Mexico" => 1714, "Canada" => 1467, "Russia" => 1218, "Argentina" => 1138, "Bolivia" => 855, "Colombia" => 836, "Paraguay" => 799, "Indonesia" => 673];
4
5
function custom_sort($word_a, $word_b) {
6
    if (strlen($word_a) < strlen($word_b)) {
7
        return -1;
8
    }
9
    if (strlen($word_a) == strlen($word_b)) {
10
        return strcmp($word_a, $word_b);
11
    }
12
    if (strlen($word_a) > strlen($word_b)) {
13
        return 1;
14
    }
15
}
16
17
uksort($airport_count, "custom_sort");
18
19
foreach($airport_count as $country=>$count) {
20
    echo str_pad($country, 15)." ".$count."\n";
21
}
22
23
/*

24
Brazil          4093

25
Canada          1467

26
Mexico          1714

27
Russia          1218

28
Bolivia         855

29
Colombia        836

30
Paraguay        799

31
Argentina       1138

32
Indonesia       673

33
United States   13513

34
*/
35
36
?>

In the above example, we have used the custom sort function from the previous section to sort the names of countries first by the length of their name and then alphabetically.

Sorting Multi-Dimensional Arrays in PHP

It is much more common in real life to deal with multi-dimensional information. For instance, institutions will store the marks of all students in a variety of subjects in a single table instead of creating new tables for each subject. If you have to store the same information in PHP, you would also prefer to do it using a multi-dimensional array instead of a separate array for each subject.

Sorting With User-Defined Functions

In this tutorial, we will learn how to sort a multi-dimensional array using a list of tallest buildings in the world as an example. Our array will contain information about the name of the building, the city and country where it is located, the number of floors, and the total height in meters, along with the year in which it was built.

When you want to sort the values in a multi-dimensional array based on a particular field, you can simply use the usort() function. The example below should help you understand this technique better.

1
<?php
2
3
$tallest_buildings = [
4
    ["Building" => "Burj Khalifa","City" => "Dubai","Country" => "United Arab Emirates","Height" => 828,"Floors" => 163,"Year" => 2010],
5
    ["Building" => "Shanghai Tower","City" => "Shanghai","Country" => "China","Height" => 632,"Floors" => 128,"Year" => 2015],
6
    ["Building" => "Abraj Al-Bait Towers","City" => "Mecca","Country" => "Saudi Arabia","Height" => 601,"Floors" => 120,"Year" => 2012],
7
    ["Building" => "Ping An Finance Center","City" => "Shenzhen","Country" => "China","Height" => 599,"Floors" => 115,"Year" => 2017],
8
    ["Building" => "Lotte World Tower","City" => "Seoul","Country" => "South Korea" ,"Height" => 554,"Floors" => 123,"Year" => 2016]
9
];
10
11
function storey_sort($building_a, $building_b) {
12
    return $building_a["Floors"] - $building_b["Floors"];
13
}
14
15
usort($tallest_buildings, "storey_sort");
16
17
foreach($tallest_buildings as $tall_building) {
18
    list($building, $city, $country, $height, $floors) = array_values($tall_building);
19
    echo $building." is in ".$city.", ".$country.". It is ".$height." meters tall with ".$floors." floors.\n";
20
}
21
22
/*

23
Ping An Finance Center is in Shenzhen, China. It is 599 meters tall with 115 floors.

24
Abraj Al-Bait Towers is in Mecca, Saudi Arabia. It is 601 meters tall with 120 floors.

25
Lotte World Tower is in Seoul, South Korea. It is 554 meters tall with 123 floors.

26
Shanghai Tower is in Shanghai, China. It is 632 meters tall with 128 floors.

27
Burj Khalifa is in Dubai, United Arab Emirates. It is 828 meters tall with 163 floors.

28
*/
29
30
?>

In the above example, the information about each building is stored in its own array inside the main $tallest_buildings array. The storey_sort() function simply subtracts the numbers of floors in the second building from the first to determine which building is smaller according to our criteria. We don't have to worry about returning a specific negative or positive value because all negative values mean smaller and all positive values mean bigger.

In the end, we just iterate through the main array and print out information about each building.

Sorting Across Multiple Columns

There is a function called array_multisort() which you can use to sort your multi-dimensional array based on the values of multiple columns or dimensions. You just need to create an array of the key values which you want to use for sorting. After that, it is just a matter of passing the sorting flags.

The following example should make it clear:

1
<?php
2
3
$players = [
4
    [
5
        'name' => 'Adam',
6
        'score' => 70,
7
        'health' => 80
8
    ],
9
    [
10
        'name' => 'Joey',
11
        'score' => 60,
12
        'health' => 90
13
    ],
14
    [
15
        'name' => 'Monty',
16
        'score' => 70,
17
        'health' => 45
18
    ],
19
    [
20
        'name' => 'Andrew',
21
        'score' => 90,
22
        'health' => 80
23
    ],
24
    [
25
        'name' => 'Sally',
26
        'score' => 60,
27
        'health' => 85
28
    ],
29
    [
30
        'name' => 'Amanda',
31
        'score' => 98,
32
        'health' => 50
33
    ],
34
    [
35
        'name' => 'James',
36
        'score' => 50,
37
        'health' => 50
38
    ]
39
];
40
41
$p_score = array_column($players, 'score');
42
$p_health = array_column($players, 'health');
43
44
array_multisort($p_score, SORT_DESC, $p_health, SORT_ASC, $players);
45
46
?>

We have a multi-dimensional array which stores the name, score, and health of players. We use the array_column() function to create two separate arrays called $p_score and $p_health which store the score and health of the players.

Notice the order in which the arrays are passed to the array_multisort() function. This will have an effect on the final result. We pass the $p_score array first, and the values in $p_score will be sorted in descending order. This will put Amanda at the top as she has the highest score. Now, the elements in the arrays $p_health and $players will also be rearranged so that Amanda's health is at the top in $p_health and she is at the top in $players.

In other words, array_multisort() will sort the whole $p_score array in descending order. Then the values in other arrays will also be rearranged to match that order. So the order will be Amanda, Andrew, Adam, Monty, etc.

Once it has gone through the whole $p_score array, it will move on to the $p_health array. You will notice that both Adam and Monty have the same score. So their ultimate position will be determined by their health values, which have to be sorted in ascending order. Monty has lower health than Adam, so he will be placed before Adam. The order of players will now become Amanda, Andrew, Monty, Adam, and so on.

All other value clashes are resolved in a similar manner. Here is the final result that you will get after sorting the array:

1
<?php
2
3
print_r($players);
4
5
/*

6
Array

7
(

8
    [0] => Array

9
        (

10
            [name] => Amanda

11
            [score] => 98

12
            [health] => 50

13
        )

14


15
    [1] => Array

16
        (

17
            [name] => Andrew

18
            [score] => 90

19
            [health] => 80

20
        )

21


22
    [2] => Array

23
        (

24
            [name] => Monty

25
            [score] => 70

26
            [health] => 45

27
        )

28


29
    [3] => Array

30
        (

31
            [name] => Adam

32
            [score] => 70

33
            [health] => 80

34
        )

35


36
    [4] => Array

37
        (

38
            [name] => Sally

39
            [score] => 60

40
            [health] => 85

41
        )

42


43
    [5] => Array

44
        (

45
            [name] => Joey

46
            [score] => 60

47
            [health] => 90

48
        )

49


50
    [6] => Array

51
        (

52
            [name] => James

53
            [score] => 50

54
            [health] => 50

55
        )

56


57
)

58
*/
59
60
?>

It might have become obvious by now, but I would still like to point out that array_multisort() will not help you save multiple sort() calls for separate arrays. Here's an example:

1
<?php
2
3
$marks_a = [60, 80, 78, 90, 63];
4
$marks_b = [81, 75, 92, 40, 35];
5
6
array_multisort($marks_a, SORT_ASC, $marks_b, SORT_ASC);
7
8
print_r($marks_a);
9
/*

10
Array

11
(

12
    [0] => 60

13
    [1] => 63

14
    [2] => 78

15
    [3] => 80

16
    [4] => 90

17
)

18
*/
19
20
print_r($marks_b);
21
/*

22
Array

23
(

24
    [0] => 81

25
    [1] => 35

26
    [2] => 92

27
    [3] => 75

28
    [4] => 40

29
)

30
*/
31
32
?>

If your intention was to sort both the arrays in ascending order independently, then array_multisort() will disappoint you badly. Your best bet in this situation is to simply call sort() separately on both the arrays.

Final Thoughts

In this tutorial, I showed you some different functions in PHP that can be used to sort arrays either by their keys or their values. We also learned how to sort an array by its keys or values using our own custom sorting criteria with the help of the uksort() and uasort() functions. The final section discussed how to sort all the values in a multi-dimensional array using only a specific field.

I hope you learned something new from this tutorial. If you have any questions or suggestions, please let me know in the comments. The best way to learn is to try and create some examples of your own, sorting arrays by using these functions.

This post has been updated with contributions from Monty Shokeen. Monty is a full-stack developer who also loves to write tutorials and to learn about new JavaScript libraries.

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.