Why Sorting Associative Arrays is a Pain (and How to Fix It)
\n\nImagine: you pulled a list of users from a database. Each has a name, age, city, and rating. The data came as an array of associative arrays. Then your boss says: "Sort by age, and then by rating in reverse order." Sound familiar? If you've ever written PHP, you've likely faced the task: sort an array of associative arrays by column value. The question with thousands of views on Stack Overflow doesn't lie — it's a real stumbling block for many developers.
\n\nIn this article, we'll cover all the ways to sort multidimensional arrays in PHP. From simple usort to powerful array_multisort. You'll learn how to sort by one field, by multiple fields, in different directions, and how to avoid pitfalls with data types. Let's go!
The Problem: Why Regular sort() Doesn't Work
\n\nLet's say we have this array:
\n\n<?php\n$users = [\n ['name' => 'Anna', 'age' => 25, 'rating' => 4.7],\n ['name' => 'Ivan', 'age' => 30, 'rating' => 3.9],\n ['name' => 'Maria', 'age' => 22, 'rating' => 4.9],\n];\n?>\n\nIf you try sort($users), PHP will issue a warning and leave the array untouched. Why? Because sort() compares elements directly, and PHP doesn't know how to compare associative arrays. It needs a hint — which field to use as the sorting criterion.
Method #1: usort() — The King of Custom Sorting
\n\nThe usort() function takes an array and a callback function that compares two elements. This is the most flexible and commonly used method.
Sorting by One Field (Ascending)
\n\n<?php\nusort($users, function($a, $b) {\n return $a['age'] <=> $b['age'];\n});\n// Result: Maria (22), Anna (25), Ivan (30)\n?>\n\nThe <=> operator (spaceship) was introduced in PHP 7 and makes the code cleaner. It returns -1, 0, or 1 based on the comparison. If you need descending order, simply swap $a and $b:
<?php\nusort($users, function($a, $b) {\n return $b['age'] <=> $a['age'];\n});\n// Result: Ivan (30), Anna (25), Maria (22)\n?>\n\nSorting by a String Field
\n\nStrings work the same way, but remember locale. If you're sorting Russian names, use setlocale() and strcoll() for correct Cyrillic handling:
<?php\nsetlocale(LC_ALL, 'ru_RU.UTF-8');\nusort($users, function($a, $b) {\n return strcoll($a['name'], $b['name']);\n});\n?>\n\nMethod #2: array_multisort() — For Sorting by Multiple Columns
\n\nWhen you need to sort first by one field and then by another (e.g., by city, and within a city by age), usort starts requiring complex logic. That's where array_multisort() comes in.
Sorting by Two Fields
\n\n<?php\n$ages = array_column($users, 'age');\n$ratings = array_column($users, 'rating');\narray_multisort($ages, SORT_ASC, $ratings, SORT_DESC, $users);\n?>\n\nLet's break down the magic: we create separate arrays from the needed columns, then pass them to array_multisort. Important: the original array is passed last — it will be reordered according to the order of the first arrays. This is a powerful but dangerous tool: if the columns have different lengths, you'll get an error.
Method #3: array_column() + sort() — A Hack for One-Liners
\n\nIf you just need to sort an array by a single numeric field, you can use a combination of array_column() and array_multisort() in one line:
<?php\narray_multisort(array_colum