OK, I'll grant that there are a lot of PHP constructs I don't understand, and I have a tendency to use simpler old school 'C' style methods. But the first goal is to get code to work as desired, and then improve it. With that in mind, a further complication I discovered is that for whatever reason, my camera security software occasionally uploads duplicate files (same content, name, and timestamp) to the different directories. So here was my overall solution to displaying the images in order, while eliminating duplicates. That last part isn't perfect yet, because so far I'm just assuming duplicate time stamps means duplicate files. But I've shown a way of keeping multiple files with dup timestamps in the comments.
So first, I modified the original block of code to also record $rawtimestamps, along with the file names, formatted time stamps, and full paths. As someone pointed out already in another answer, the raw timestamp integers will certainly be easier to sort.
$dir_path = "private/cats/";
$extensions_array = array('jpg','png','jpeg','JPG','PNG','JPEG');
$total = 0;
$objects = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir_path), RecursiveIteratorIterator::LEAVES_ONLY);
foreach($objects as $filepath => $object)
$fileinfo = pathinfo($filepath);
// skip if no extension, or extension not in my allowed list
if (!isset($fileinfo['extension'])) continue;
if (!in_array($fileinfo['extension'], $extensions_array)) continue;
$rawTimestamps[$total] = filemtime($filepath); // <- new addition.
$timestamps[$total] = date("F d Y H:i:s", filemtime($filepath));
$filenames[$total] = $fileinfo['filename'] . "." . $fileinfo['extension'];
$filepaths[$total] = $filepath;
Then I concocted this brute force loop to create a new array called $indexes. It will serve as a mapping table, holding indexes to progressively higher timestamps in the original arrays.
$max = max($rawTimestamps);
for ($i=0; $i < $total; $i++)
$lowest = min($rawTimestamps);
if ($lowest > $max) break; // stop when no more.
for ($j= 0; $j < $total; $j++)
if ($rawTimestamps[$j] != $lowest) continue;
$indexes[$newtotal] = $j; // keep index. overwrite duplicates
$rawTimestamps[$j] = $max+1; // ensure never counted again.
$newtotal++; // ** this is the new real total
What is happening here is that I've used the max() function to record the highest value in the $rawtimestamp array. Then in the outer loop I record the $lowest value in the raw timestamp array, exiting when lowest number found is greater than the max value originally found. This will jmake sense in a moment. In the inner loop I look for that 'lowest' timestamp and when i find it, I place the index ($j) to where it was found in my new $indexes array. I then replace the raw time stamp with a number greater than the originally found max value. That way it won't be found by the inner loop again. This destroys $rawtimeatamps as the process continues, but I won't need them anymore. When the lowest timestamp found is equal to the originally determined max value, that means all the $rawtimestamps have been replaced, and the loop exists with a break;
Note that the $newTotal is counted and used to reference where the subsequent $indexes are stored. If duplicate timestamps are found, they get overwritten, because the $newtotal is not incremented until the inner loop exits. If I wanted to keep multiple files with the same timestamp, comment out where $newtotal is incremented, and change this line so the total increments each time a value is placed in $indexes...
$indexes[$newtotal++] = $j; // keep index and do NOT overwrite duplicates
So now all I needed to do was modify my display loop. Instead of indexing my filenames directly, I use my $indexes "map" to "look up" the file data according to progressively higher timestamps, as I display them.
echo "<h1>$newtotal Image Files</h1>";
for ($i=0; $i < $newtotal; $i++)
$ix= $indexes[$i]; // get index to progressively older files
echo "<br><hr><h1>$filenames[$ix] $timestamps[$ix] <br></h1>";
echo "<img src='$filepaths[$ix]' style='width:100%;height:auto;'><br>";
Again, I'm sure this is not an eloquent solution, but it works. If anyone wishes to offer a better way to do what I did here, I'm happy to learn.