[HELP] - PHP Sort Multi-Dimensional Array

Discussion in 'PHP' started by farhan91, Oct 25, 2010.

  1. #1
    Hello every. I have a php question regarding sorting multi-dimensional arrays. I have a file upload script and I want to be able to sort the files by file name and by file size. So far I am able to use the 'sort()' function to get it to sort just the file name, but it does not work with file names starting with capital letters.

    I am using this code to do this:
    if ($_GET['act'] == "sortby") {
    				if ($_GET['col'] == "filename") {
    					sort($photos);
    				}				
    			}
    PHP:
    After searching around on the internet, I have found that people have used the 'usort()' function to accomplish this task but I have not been successful with it :(

    Here is the print_r output for the arrays:
    $photos[] = Array
    (
        [0] => Array
            (
                [FILENAME] => ruit_candles.jpg
                [FILENAMEDIR] => images/ruit_candles.jpg
                [SIZE] => 22.48
                [DATE] => October 21, 2010 12:04:49 pm
            )
    
        [1] => Array
            (
                [FILENAME] => Fuit_candles.jpg
                [FILENAMEDIR] => images/Fuit_candles.jpg
                [SIZE] => 22.48
                [DATE] => October 21, 2010 13:00:29 pm
            )
    
        [2] => Array
            (
                [FILENAME] => fishflush.jpg
                [FILENAMEDIR] => images/fishflush.jpg
                [SIZE] => 22.695
                [DATE] => October 14, 2010 19:10:50 pm
            )
    
        [3] => Array
            (
                [FILENAME] => uieiuirdi.jpg
                [FILENAMEDIR] => images/uieiuirdi.jpg
                [SIZE] => 13.243
                [DATE] => October 14, 2010 12:44:05 pm
            )
    
    Code (markup):
    Thanks in advance :)
     
    farhan91, Oct 25, 2010 IP
  2. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #2
    Assuming your using MySQL and $_GET['col'] (is the column name) you can do the sorting within your query, e.g.

    //the valid column names (security purposes)
    $valid_columns = array('filename', 'filesize');
    
    $sort = isset($_GET['col']) && isset($_GET['act']) && $_GET['act'] == 'sortby' && in_array($_GET['col'], $valid_columns) ? " ORDER BY {$_GET['col']}" : NULL;
    
    $sql = "SELECT something FROM table{$sort}";
    
    $query = mysql_query($sql);
    
    $row = mysql_fetch_array($query);
    PHP:
     
    Last edited: Oct 25, 2010
    danx10, Oct 25, 2010 IP
  3. farhan91

    farhan91 Peon

    Messages:
    48
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #3
    No I am not using mysql. Its a php script.

    Heres what im doing:
    // Copy File From Temp Dir to Images Dir	
    if ($_SERVER['REQUEST_METHOD'] == 'POST' ) {
    	// print_r($_FILES);
    	if (copy ($_FILES['userfile']['tmp_name'], $images_dir. $_FILES['userfile']['name']) == false){
    		echo "Copy failed";
    	}
    }
    	
    if ($handle = opendir('./' . $images_dir)) {
        while (false !== ($file = readdir($handle))) {
            if ($file != "." && $file != "..") {
               $photos[] = array(
    					   	'FILENAME' => $file, // Get File Name
    					   	'FILENAMEDIR' => $images_dir . $file, // Get File Name With Directory Name
    						'SIZE' => round(filesize($images_dir . $file) / 1024, 3), // Get File Size
    						'DATE' => date("F d, Y H:i:s a", filemtime($images_dir . $file))); // Get File Make Time / Date
            }
        }
        closedir($handle);
    }			
    PHP:
    And This to print out files in a table:
    <table> 
    			<tr> 
    			  <th>File Name (<a href="upload.php?act=sortby&col=filename">sort</a>)</th> 
    			  <th>Size KBytes (<a href="upload.php?act=sortby&col=size">sort</a>)</th> 
    			  <th>Date</th> 
    			  <th></th> 
    			   <th></th> 
    			</tr> 
                <?
    			// Sort By Name
    			if ($_GET['act'] == "sortby") {
    				if ($_GET['col'] == "filename") {
    					sort($photos);
    				}				
    			}
    			?>            
    			<? foreach ( $photos as $key => $row): ?>
                <? $even_odd = ($count%2 == 0)?"even":"odd"; ?>
                <tr class='<?= $even_odd ?>' >
                <? $count++; ?>
                
                <!-- File Name -->
    			<td><a href="<?= $images_dir . $row['FILENAME'] ?>" ><?= $row['FILENAME'] ?></a></td> 
    
    			<!-- Size -->
                <td><?= $row['SIZE'] ?></td>
    
                <!-- Date --> 
    			<td><?= $row['DATE'] ?></td> 
    
                <!-- View -->
    			<td><a href="#" onClick="popup('<?= $row['FILENAMEDIR'] ?>')"  >View</a></td> 
    
                <!-- Delete -->
                <td align=center><a href="upload.php?act=del&file=<?= $row['FILENAME'] ?>">Delete</a></td> 
    			</tr> 
                <? endforeach; ?>
    					  </table>
    PHP:
     
    farhan91, Oct 25, 2010 IP
  4. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #4
    Firstly use move_uploaded_file() instead of copy() (refer to the documentation as to why), also I hope your validating the $_FILES['userfile']['name'] (to limit it to specific file extensions - to only allow images?)...

    Answering your initial question:

    function array_msort($array, $cols)
    {
        $colarr = array();
        foreach ($cols as $col => $order)
        {
            $colarr[$col] = array();
            foreach ($array as $k => $row)
            {
                $colarr[$col]['_'.$k] = strtolower($row[$col]);
            }
        }
        $params = array();
        foreach ($cols as $col => $order)
        {
       
            $params[] =&$colarr[$col];
            $order=(array)$order;
            foreach($order as $order_element)
            {
                //pass by reference, as required by php 5.3
                $params[]=&$order_element;
            }
        }
        call_user_func_array('array_multisort', $params);
        $ret = array();
        $keys = array();
        $first = true;
        foreach ($colarr as $col => $arr)
        {
            foreach ($arr as $k => $v)
            {
                if ($first)
                {
                    $keys[$k] = substr($k,1);
                }
                $k = $keys[$k];
               
                if (!isset($ret[$k]))
                {
                    $ret[$k] = $array[$k];
                }
               
                $ret[$k][$col] = $array[$k][$col];
            }
            $first = false;
        }
        return $ret;
    }
    
    //replace sort($photos); with the following line...
    $photos = array_values(array_msort($photos, array('FILENAME'=>SORT_ASC)));
    PHP:
    Function borrowed from http://www.php.net/manual/en/function.array-multisort.php#95258

    Untested, but should work.
     
    danx10, Oct 25, 2010 IP
  5. farhan91

    farhan91 Peon

    Messages:
    48
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #5
    Is there a way to do this using:
    usort()
    PHP:
     
    farhan91, Oct 25, 2010 IP