phparrayssortingnatsort

php natsort() not working as supposed to


I have a folder with 500+ jpgs named 1.jpg, 2.jpg, 3.jpg, ... 205.jpg etc. I need to output links to them in a table sorted by number.

After I natsort() an array of filenames and print_r it right away it outpust correctly, but when I try to loop through it and output in an html table it goes 1.jpg 10.jpg 100.jpg 101.jpg 102.jpg 104.jpg 105.jpg 106.jpg 107.jpg 108.jpg etc.

Here's my code:

<?php
$dir = 'files/'; // folder with 500+ images named 1.jpg, 2.jpg, 3.jpg, ... 505.jpg etc.
$files = scandir($dir);

natsort($files);
print_r($files); // here outputs correctly: 'Array ( [0] => . [1] => .. [2] => 1.jpg [106] => 2.jpg [213] => 3.jpg [324] => 4.jpg [432] => 5.jpg [543] => 6.jpg [652] => 7.jpg [699] => 8.jpg...'

$cols = 10;

echo "<table>";
$k = 0;
for ($i = 0; $i < count($files); $i++) {
 if (($files[$i] != ".") && ($files[$i] != "..")) {
  if ($k % $cols == 0) {
   echo "<tr>";
  }
  echo "<td width='70px' align='center'>";
  $path = $dir . $files[$i];
  echo "<a href='$path'>";
  echo "$files[$i]";
  echo "</a>";
  echo "</td>";
  if ((($k + 1) % $cols == 0) || (($i + 1) == count($files))) {
   echo "</tr>";
  }

  $k++;
 }
}
echo "</table>";

Solution

  • As you'll notice from your print_r of the result of the natsort, the keys have just been reordered, not renumbered, in the $files array. So when you loop on $files[$i] you get the same ordering as you started with. So you have two alternatives: use a foreach or use array_values to renumber the keys. Here's a small demo:

    $files = array("12.png", "10.png", "2.png", "1.png");
    print_r($files);
    natsort($files);
    print_r($files);  
    for ($i = 0; $i < count($files); $i++) {
        echo $files[$i] . "\n";
    }
    foreach ($files as $file) {
        echo $file . "\n";
    }
    $files = array_values($files);
    for ($i = 0; $i < count($files); $i++) {
        echo $files[$i] . "\n";
    }
    

    Output:

    Array
    (
        [0] => 12.png
        [1] => 10.png
        [2] => 2.png
        [3] => 1.png
    )
    
    Array
    (
        [3] => 1.png
        [2] => 2.png
        [1] => 10.png
        [0] => 12.png
    )
    
    12.png
    10.png
    2.png
    1.png
    
    1.png
    2.png
    10.png
    12.png
    
    1.png
    2.png
    10.png
    12.png