Sorting a PHP multi-column array

PHP support for arrays is fantastic, particularly for those of us with a history using ASP. Sorting a single-column array is straightforward (there is a sort() function). But what about sorting a multi-column array? Well, there is a function (array_multisort()) that does it, but understanding how to use it is a challenge. This article hopefully provides a simpler explanation.

If you are using a multi-column array to store data from a database, it is much simpler and faster to get the data directly from the database in the order required (use the ORDER BY clause in your SELECT statement).  This function is best used for multi-column arrays that are generated locally, or only in part from a database.

How to

To sort a multi-column array:

  1. determine which columns you want to sort by
  2. for each column you want to sort by, copy its contents into a separate, single-column array
  3. build your array_multisort() command:
    • add the new single-column array as a parameter
    • optionally follow the array with parameters for sort order and type
    • repeat above two steps for each column to be sorted on
    • complete command with name of multi-column array to be sorted

sort type and order

Sort type can be:

  • SORT_REGULAR – compare/sort normally (default)
  • SORT_NUMERIC – compare/sort as numbers
  • SORT_STRING – compare/sort as strings

Sort regular uses standard ASCII order (“ABa” is 3 characters in regular order). The other two options operate more logically (eg “aAB” is the same characters now in string order).

Sort order can be:

  • SORT_ASC – ascending order (default)
  • SORT_DESC – descending order

For example…

For example. here’s a 3-column array we want to sort:

  $data[0]['name']= 'Google';
  $data[0]['url'] = '';
  $data[0]['rank'] = 45;

  $data[1]['name']= 'Yahoo';
  $data[1]['url'] = '';
  $data[1]['rank'] = 17;

  $data[2]['name']= 'MSN';
  $data[2]['url'] = '';
  $data[2]['rank'] = 6;

Assume we want to sort this array by rank (ascending order). The first step is to store the rank column as a separate, single-column array. This is easy to do using the foreach command:

  foreach ($data as $val)
    $sortArrayRank[] = $val['rank'];

To sort by this column, use array_multisort and pass our newly created rank array as the first parameter:

  array_multisort($sortArrayRank, $data);

To change the sort to descending order, add the required order parameter after the 1-column array:

  array_multisort($sortArrayRank, SORT_DESC, $data);

To sort by more than one column (eg to sort by rank, then name), simply repeat the above steps for the subsequent column(s) and add the paramaters to the list.

  foreach ($data as $val)
    $sortArrayName[] = $val['name'];
  array_multisort($sortArrayRank, SORT_DESC, $sortArrayName, $data);

more information

The official explanation of array_multisort can be found in the PHP manual.

11 thoughts on “Sorting a PHP multi-column array

  1. Alan Berman

    I have been dealing with a sorting issue for a publisher catalog on and off for years. I finally found this page and you have explained everything so well that I was able to get the site just as I want it. Thank you for taking the time to post such a concise (and accurate) tutorial.

  2. Anonymous

    Have you ever thought about publishing an ebook or guest authoring on other websites?
    I have a blog based upon on the same topics you discuss and would really like to have you share some stories/information.
    I know my visitors would value your work. If you’re even remotely interested, feel free to send me an email.

  3. Heather

    This is the 4th posting, of urs I actually read.
    And yet I actually love this particular one, “Sorting a PHP multi-column array” the very best.
    Regards ,Barb


Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>