Skip to Content
Course content

94: usort, uasort, uksort

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I remember the first time I tried to sort a map of database records in PHP. I had an array where the keys were the user IDs and the values were the user profiles. I wanted to sort them alphabetically by name, so I reached for usort(). It worked perfectly—until I tried to access a specific user by their ID and realized my IDs had vanished, replaced by a generic 0, 1, 2 sequence. I'd accidentally wiped out my primary keys.

The disappearing key mystery

$users = [
    1042 => ['name' => 'Zelda', 'email' => 'z@example.com'],
    1021 => ['name' => 'Alice', 'email' => 'a@example.com'],
    1088 => ['name' => 'Bob', 'email' => 'b@example.com'],
];

// I want to sort these users by name
usort($users, function($a, $b) {
    return strcmp($a['name'], $b['name']);
});

// Now I try to find Alice using her ID
echo $users[1021]['name']; // Fatal error: Uncaught Error: Undefined array key 1021

If you run this, you'll see exactly what happened to me. usort() is great for simple lists, but it doesn't care about your keys. It treats the array as a indexed list and re-indexes everything starting from zero. In a real application, this is a disaster because you've just lost the link between your data and your database IDs.

Saving the associations with uasort

To fix this, you need uasort(). The "a" in the middle stands for "associative." It does the exact same thing as usort()—it lets you define a custom comparison function—but it preserves the key-value relationship.

$users = [
    1042 => ['name' => 'Zelda', 'email' => 'z@example.com'],
    1021 => ['name' => 'Alice', 'email' => 'a@example.com'],
    1088 => ['name' => 'Bob', 'email' => 'b@example.com'],
];

uasort($users, function($a, $b) {
    // Using the spaceship operator (<=>) is the modern way to do this.
    // It returns -1, 0, or 1 automatically.
    return $a['name'] <=> $b['name'];
});

echo $users[1021]['name']; // Works! Outputs: Alice

Now, Alice is still at key 1021, but she's moved to the front of the array. I highly recommend using the spaceship operator (<=>) introduced in PHP 7. It's much cleaner than strcmp() or writing nested if-statements to return -1, 0, or 1.

Sorting by the keys themselves with uksort

Sometimes, the values aren't what you care about—you want to sort by the keys, but the default ksort() isn't flexible enough. For example, what if your keys are strings that represent complex codes (like "PROD-10", "PROD-2", "PROD-1") and you want them sorted numerically rather than alphabetically?

That's where uksort() comes in. The "k" stands for "key." Instead of comparing the values $a and $b, the callback function receives the keys.

$inventory = [
    'PROD-10' => 'Widget A',
    'PROD-2'  => 'Widget B',
    'PROD-1'  => 'Widget C',
];

uksort($inventory, function($keyA, $keyB) {
    // Strip the 'PROD-' prefix and compare as integers
    $numA = (int) str_replace('PROD-', '', $keyA);
    $numB = (int) str_replace('PROD-', '', $keyB);
    return $numA <=> $numB;
});

// The array is now sorted: PROD-1, PROD-2, PROD-10

Just remember the cheat sheet for these three:

  • usort: Sorts values, kills keys.
  • uasort: Sorts values, keeps keys.
  • uksort: Sorts keys, using a custom function.



📋 Practical Task

Building a Prioritized Product Catalog Sorter

You are building a product listing page. You have an array of products where the key is the SKU and the value is an array containing the product name and a "priority" score (higher score means higher priority). Some products are "featured" and should always appear first, regardless of their priority score.

Your Task: Use uasort() to sort the following array. The sorting logic should be:

  1. If one product is featured and the other isn't, the featured one comes first.
  2. If both are featured (or both are not), the one with the higher priority score comes first.
  3. Preserve the SKU keys.
$products = [
    'SKU-001' => ['name' => 'Basic Tee', 'priority' => 10, 'featured' => false],
    'SKU-002' => ['name' => 'Fancy Hat', 'priority' => 5, 'featured' => true],
    'SKU-003' => ['name' => 'Cool Shoes', 'priority' => 20, 'featured' => false],
    'SKU-004' => ['name' => 'Gold Watch', 'priority' => 15, 'featured' => true],
];

// Write your uasort implementation here
Rating
0 0

There are no comments for now.

to be the first to leave a comment.