## Sorting Multidimensional Arrays

Sorting arrays with more than one dimension, or by something other than alphabetical or numerical order, is more complicated. PHP knows how to compare two numbers or two text strings, but in a multidimensional array, each element is an array. PHP does not know how to compare two arrays, so you need to create a method to compare them. Most of the time, the order of the words or numbers is fairly obvious—but for complicated objects, it becomes more problematic.

### User Defined Sorts

Here is the definition of a two-dimensional array we used earlier. This array stores Bob's three products with a code, a description, and a price for each.

$products = array( array( 'TIR', 'Tires', 100 ), array( 'OIL', 'Oil', 10 ), array( 'SPK', 'Spark Plugs', 4 ) );

If we sort this array, what order will the values end up in? Because we know
what the contents represent, there are at least two useful orders. We might want
the products sorted into alphabetical order using the description or by numeric
order by the price. Either result is possible, but we need to use the function
`usort()` and tell PHP how to compare the items. To do this, we need to
write our own comparison function.

The following code sorts this array into alphabetical order using the second column in the array—the description.

function compare($x, $y) { if ( $x[1] == $y[1] ) return 0; else if ( $x[1] < $y[1] ) return -1; else return 1; } usort($products, 'compare');

So far in this book, we have called a number of the built-in PHP functions. To sort this array, we have defined a function of our own. We will examine writing functions in detail in Chapter 5, "Reusing Code and Writing Functions," but here is a brief introduction.

We define a function using the keyword `function`. We need to give the
function a name. Names should be meaningful, so we'll call it
`compare()`. Many functions take parameters or arguments. Our
`compare()` function takes two, one called `x` and one called
`y`. The purpose of this function is to take two values and determine
their order.

For this example, the `x` and `y` parameters will be two of the
arrays within the main array, each representing one product. To access the
`Description` of the array `x`, we type `$x[1]` because the
`Description` is the second element in these arrays, and numbering starts
at zero. We use `$x[1]` and `$y[1]` to compare the
`Description`s from the arrays passed into the function.

When a function ends, it can give a reply to the code that called it. This is
called *returning* a value. To return a value, we use the keyword
`return` in our function. For example, the line `return 1;` sends
the value `1` back to the code that called the function.

To be used by `usort()`, the `compare()` function must compare
`x` and `y`. The function must return `0` if `x`
equals `y`, a negative number if it is less, and a positive number if it
is greater. Our function will return `0`, `1`, or
`–1`, depending on the values of `x` and `y`.

The final line of code calls the built-in function `usort()` with the
array we want sorted ($`products`) and the name of our comparison
function (`compare()`).

If we want the array sorted into another order, we can simply write a different comparison function. To sort by price, we need to look at the third column in the array, and create this comparison function:

function compare($x, $y) { if ( $x[2] == $y[2] ) return 0; else if ( $x[2] < $y[2] ) return -1; else return 1; }

When `usort($products, compare)` is called, the array will be placed
in ascending order by price.

The "u" in `usort()` stands for "user" because
this function requires a user-defined comparison function. The `uasort()`
and `uksort()` versions of `asort` and `ksort` also require
a user-defined comparison function.

Similar to `asort()`, `uasort()` should be used when sorting an
associative array by value. Use `asort` if your values are simple numbers
or text. Define a comparison function and use `uasort()` if your values
are more complicated objects such as arrays.

Similar to `ksort()`, `uksort()` should be used when sorting an
associative array by key. Use `ksort` if your keys are simple numbers or
text. Define a comparison function and use `uksort()` if your keys are
more complicated objects such as arrays.

### Reverse User Sorts

The functions `sort()`, `asort()`, and `ksort()` all
have a matching reverse sort with an "r" in the function name. The
user-defined sorts do not have reverse variants, but you can sort a
multidimensional array into reverse order. You provide the comparison function,
so write a comparison function that returns the opposite values. To sort into
reverse order, the function will need to return `1` if `x` is less
than `y` and `–1` if `x` is greater than `y`.
For example,

function reverseCompare($x, $y) { if ( $x[2] == $y[2] ) return 0; else if ( $x[2] < $y[2] ) return 1; else return -1; }

Calling `usort($products, reverseCompare)` would now result in the
array being placed in descending order by price.