Sort array of associative arrays on multiple columns using specified sorting rules
In PHP 5.3 every parameter in the array has to be a reference when calling array_multisort()
with call_user_func_array()
.
This function sorts a multidimensional array and shows a way to build an array of referenced params that works correctly.
function msort()
{
$params = func_get_args();
$array = array_pop($params);
if (!is_array($array))
return false;
$multisort_params = array();
foreach ($params as $i => $param)
{
if (is_string($param))
{
${"param_$i"} = array();
foreach ($array as $index => $row)
{
${"param_$i"}[$index] = $row[$param];
}
}
else
${"param_$i"} = $params[$i];
$multisort_params[] = &${"param_$i"};
}
$multisort_params[] = &$array;
call_user_func_array("array_multisort", $multisort_params);
return $array;
}
Example:
$data is the given array from the question
$sorted_data = msort('city', SORT_ASC, SORT_STRING, 'zip', SORT_DESC, SORT_NUMERIC, $data)
This should work for the situation you describe.
usort($arrayToSort, "sortCustom");
function sortCustom($a, $b)
{
$cityComp = strcmp($a['city'],$b['city']);
if($cityComp == 0)
{
//Cities are equal. Compare zips.
$zipComp = strcmp($a['zip'],$b['zip']);
if($zipComp == 0)
{
//Zips are equal. Compare last names.
return strcmp($a['last_name'],$b['last_name']);
}
else
{
//Zips are not equal. Return the difference.
return $zipComp;
}
}
else
{
//Cities are not equal. Return the difference.
return $cityComp;
}
}
You could condense it into one line like so:
function sortCustom($a, $b)
{
return ($cityComp = strcmp($a['city'],$b['city']) ? $cityComp : ($zipComp = strcmp($a['zip'],$b['zip']) ? $zipComp : strcmp($a['last_name'],$b['last_name'])));
}
As far as having a customizable sort function, you're reinventing the wheel. Take a look at the array_multisort()
function.