PHPology is a collective of highly skilled, award winning, web gurus.
Contact Raj on 07985 467 213 or email info@phpology.co.uk

Multisorting columns in a 3D array with PHP

Today (Tuesday 4th Auguest '09) was put in a situation where I had to reorder one of the columns from my 3D array and initially started to use array_multisort as described on php.net.
Getting annoyed that it was not giving me what I needed, I started to read through the comments others had left, and tried cagret at gmail dot com example which worked a treat for me.

Basically, from my array output below, I wanted to reorder the array by 'ymd_date':

Array
(
    [0] => Array
        (
            [title] => SimpleXMLElement Object
                (
                    [0] => novolume: Is it just me or are there too few acronyms used in web design? More of them please!
                )

            [twitter_date] => SimpleXMLElement Object
                (
                    [0] => Mon, 03 Aug 2009 15:22:01 +0000
                )

            [ymd_date] => 2009-08-03 16:22:01
        )

    [1] => Array
        (
            [title] => SimpleXMLElement Object
                (
                    [0] => adamgraham: Very much enjoyed this month's Facebook Garage. Especially the talk from VCCP on the 'compare the merecat' campaign.
                )

            [twitter_date] => SimpleXMLElement Object
                (
                    [0] => Wed, 22 Jul 2009 21:48:03 +0000
                )

            [ymd_date] => 2009-07-22 22:48:03
        )

    [2] => Array
        (
            [title] => SimpleXMLElement Object
                (
                    [0] => rajgorsia: any one played with php symfony?
                )

            [twitter_date] => SimpleXMLElement Object
                (
                    [0] => Fri, 31 Jul 2009 15:51:11 +0000
                )

            [ymd_date] => 2009-07-31 16:51:11
        )
)

Using the above output assigned to a variable called $temp_array, the below code was magic.

$temp_array = array_multi_sort($temp_array, array('ymd_date'=>SORT_DESC));
//$temp_array = array_multi_sort($temp_array, array('ymd_date'=>SORT_DESC, 'title'=>SORT_ASC)); // if you want to add in another column to order

function array_multi_sort($array, $cols)
{
    $colarr = array();
    foreach($cols as $col => $order)
    {
        $colarr[$col] = array();
        foreach ($array as $k => $row)
        {
            $colarr[$col]['_'.$k] = strtolower($row[$col]);
        }
    }

    $eval = 'array_multisort(';
    foreach($cols as $col => $order)
    {
        $eval .= '$colarr[''.$col.''],'.$order.',';
    }
    $eval = substr($eval,0,-1).');';
    eval($eval);
    $ret = array();
    foreach($colarr as $col => $arr)
    {
        foreach($arr as $k => $v)
        {
            $k = substr($k,1);
            if (!isset($ret[$k])) $ret[$k] = $array[$k];
            $ret[$k][$col] = $array[$k][$col];
        }
    }
    return $ret;
}