Update
I recently answered this question in a much more capable way in the "final" topic on sorting multidimensional arrays. You can safely read the rest of this answer and immediately follow the link for a more efficient solution.
Original answer
The uasort function allows you to define your own comparison function. Just indicate all the criteria you want in this.
For example, to sort by birthday, and then by name:
function comparer($first, $second) { // First see if birthdays differ if ($first['birthday'] < $second['birthday']) { return -1; } else if ($first['birthday'] > $second['birthday']) { return 1; } // OK, birthdays are equal. What else? if ($first['name'] < $second['name']) { return -1; } else if ($first['name'] > $second['name']) { return 1; } // No more sort criteria. The two elements are equal. return 0; }
I ignore the fact that in your example, the birthdays are not in a format that can be ordered by simple comparison using the < operator. In practice, you first convert them to a trivially compatible format.
Update: if you think keeping a bunch of these multicriteria collators can get ugly, you'll find me in agreement. But this problem can be solved like any other in computer science: just add another level of abstraction.
I will assume PHP 5.3 for the following example to use the convenient syntax of the anon function. But basically you can do the same with create_function .
function make_comparer() { $criteriaNames = func_get_args(); $comparer = function($first, $second) use ($criteriaNames) { // Do we have anything to compare? while(!empty($criteriaNames)) { // What will we compare now? $criterion = array_shift($criteriaNames); // Do the actual comparison if ($first[$criterion] < $second[$criterion]) { return -1; } else if ($first[$criterion] > $second[$criterion]) { return 1; } } // Nothing more to compare with, so $first == $second return 0; }; return $comparer; }
Then you can:
uasort($myArray, make_comparer('birthday', 'name'));
This example may be trying to be too smart; In general, I do not like to use functions that do not accept their arguments by name. But in this case, the use case is a very strong argument in favor of being too smart.