Profile picture for user admin
Daniel Sipos
01 Sep 2014

Have you ever had to sort an array in PHP? There are a bunch of functions available, the most common being sort(). This function does a default sorting of the values in your array. So if you have numbers or want to do alphabetical sorting, sort() will get the job done.

But what if you require a more complex sorting logic? Let's say you have an array of names that need to be sorted in a specific order. I don't know, because your client says so. Let me show you how.

Let's say your DB returns a list of names in an array:

$names = array("Christian", "Daniel", "Adrian");

And your client says they need to be arranged in the following order: Adrian, Christian, Daniel. You can use the usort() function together with a comparator function you write yourself. How does this system work?

As a second argument of the usort() function, we pass in the name of our custom comparator function. The way this gets processed is that all the values in the array that needs sorting are passed to this function 2 at the time (usually you'll see them as $a and $b). This is done to determine which one takes precedence over which. The comparator has to return 0 if the 2 values are considered equal, a negative integer if the first value is less than the second value or a positive integer if the second value is less than the first. What less means is up to you to determine. So let's put this in practice with our example:

function _name_comparer($a, $b) {
  $correct_order = array("Adrian", "Christian", "Daniel");
  
  $a_key = array_search($a, $correct_order);
  $b_key = array_search($b, $correct_order);
  
  if ($a_key == $b_key) {
      return 0;
    }
    
    return ($a_key < $b_key) ? -1 : 1;
  }
  
usort($names, "_name_comparer");

So what happens in my comparator function? First, I create an array that contains the proper order of the names. This means that each value has an integer key that can be easily compared (and that I store in the $a_key and $b_key variables). After comparing these, I return 0, a negative or positive integer. The result is that the $names array gets resorted in the order they appear in the $correct_order local variable I created. And that's it.

If the $names variable is associative and you need to maintain the keys as they were, you can use the uasort() function:

$names = array(
  "christian" => "Christian", 
  "daniel" => "Daniel", 
  "adrian" => "Adrian",
);
uasort($names, "_name_comparer");

The comparator function can stay the same, but the uasort() function will take into account and maintain the index association of your values.

And that's it. Hope this helps.

Profile picture for user admin

Daniel Sipos

CEO @ Web Omelette

Danny founded WEBOMELETTE in 2012 as a passion project, mostly writing about Drupal problems he faced day to day, as well as about new technologies and things that he thought other developers would find useful. Now he now manages a team of developers and designers, delivering quality products that make businesses successful.

Contact us

Comments

Anonnonon 02 Sep 2014 18:10

Let the DB engine do the sorting

Nice post outlining how to use the sorts. Just a quick tip from a former uasort() abuser: Let the database engine do the sorting where possible. Especially for simple alphabetical sorts.

Sorting in PHP can be expensive but database engines like MySQL are designed and optimized to perform sorting operations. Where possible (and especially when easy), write the sorting logic into the query. For a simple alphabetical sort, the ORDER BY operator should suffice. If the sort is complex (or the PHP dev isn't well versed in SQL), it may be best to go ahead and use that uasort() now and consult a SQL specialist later if and when performance becomes a concern.

Navin 18 Sep 2017 10:55

One small doubt

Thank you. This post is clear and I easily understood this. But i want to know how the sorting actually works. The compare function is going to return 0 or 1 or -1. Using that integers, how usort functions sort.
Lets say, in your example, what exact value is assigned to ~~~$a~~~ argument and ~~~$b~~~ argument, during the first turn. If ~~~$a="christian"~~~ and ~~~$b="daniel"~~~ , then compare function will return 1. Now, how will usort function sort those two names (i.e. which name comes first on comparing those two names).
I am currently learning PHP and thank you in advance.

Add new comment