I have a camera motion detect system i use for watching my cats, and it FTP’s all its images to a folder in my hosting. So I cobbled together this code from examples I found, to display all the images along with the filenames and timestamps. Unfortunately the camera software insists on creating subfolders for each camera and each day, so I had to use this RecursiveIteratorIterator class to gather and display all the images. In the below, you can see where I build up 3 arrays of all the filenames, timestamps, and fullpaths for display. It works but all the photos were completely out of order. How can I modify this so that all the files are displayed sorted by time stamps. I *think
<!DOCTYPE html>
<html>
<body>
<?php
$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;
$timestamps[$total] = date(“F d Y H:i:s”, filemtime($filepath));
$filenames[$total] = $fileinfo[‘filename’] . “.” . $fileinfo[‘extension’];
$filepaths[$total] = $filepath;
$total++;
}
echo “<h1>$total Image Files</h1>”;
for ($i=0; $i < $total; $i++)
{
echo “<br><hr><h1>$filenames[$i] $timestamps[$i] <br></h1>”;
echo “<img src=’$filepaths[$i]’ style=’width:100%;height:auto;’><br>”;
}
?>
</body>
</html>
$dir_path = "images/";
$extensions_array = array('jpg','png','jpeg','JPG','PNG','JPEG');
$total = 0;
<br/>
<i> </i>$objects = new RecursiveIteratorIterator(
<i> </i>new RecursiveDirectoryIterator($dir_path),
<i> </i>
<i> </i>RecursiveIteratorIterator::LEAVES_ONLY);
<i> </i>$fi = [];
<i> </i>foreach($objects as $filepath => $object)
<i> </i>{
<i> </i> $fileinfo = pathinfo($filepath);
<i> </i> // skip if no extension, or extension not in my allowed list
<i> </i> if (!isset($fileinfo['extension'])) continue;
<i> </i> if (!in_array($fileinfo['extension'], $extensions_array)) continue;
<i> </i>
<i> </i> $fi[] = ["time" => filemtime($filepath),
<i> </i> "timestamp" =>date("F d Y H:i:s", filemtime($filepath)),
<i> </i> "filename"=>$fileinfo['filename'] . "." . $fileinfo['extension'],
<i> </i> "filepath" =>$filepath];
<i> </i> $timestamps[$total] = date("F d Y H:i:s", filemtime($filepath));
<i> </i> $filenames[$total] = $fileinfo['filename'] . "." . $fileinfo['extension'];
<i> </i> $filepaths[$total] = $filepath;
<i> </i>
<i> </i> $total++;
<i> </i>}
<i> </i>var_dump($fi);
<i> </i>usort($fi, function($a, $b)
<i> </i>{
<i> </i> return ($a['time'] - $b['time']);
<i> </i>});
<i> </i>var_dump($fi);
<?php
function out($val, $key){
echo "$key = $valn";
}
$fruits = array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple");
echo "<hr>asort<br>";
asort($fruits);
array_walk($fruits,"out");
echo "<hr>arsort<br>";
arsort($fruits);
array_walk($fruits,"out");
echo "<hr>rsort<br>";
rsort($fruits);
array_walk($fruits,"out");
echo "<hr>sort<br>";
sort($fruits);
array_walk($fruits,"out");
echo "<hr>";
?>
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.
}
>@PeterPan_321#1598006
**[color=#069] **
I still wish I knew the proper way to post code on this board.[/color]
ONCE I master associative arrays[/quote]It's highly recommendable to make yourself familiar with associative arrays at first. When dealing with a database later you will benefit from it as the syntax for dealing with result sets is similar or equal. When using PDO and a prepared statement, with named parameters these are handed over in an associative array.
If I simply sorted that array, I would lose all the original index references I needed.[/quote]PHP has many built in functions and it seems to me there is one that can do your task:
$timestamps = [4000, 3000, 5000, 2000];
$filepaths = ["imga.jpg", "imgb.jpg", "imgc.jpg", "imgd.jpg"];
array_multisort($timestamps, $filepaths);
var_dump($timestamps);
var_dump($filepaths);
It verifies that this function performs kind of synchronized sorting of the two arrays.php >
[code=php]
14:25 $ php -a
Interactive shell
php > $my_array = array('one', 'two');
php > $my_array[] = 'threeeee';
php > var_export($my_array);
array (
0 => 'one',
1 => 'two',
2 => 'threeeee',
)
php > $my_array[2] = 'three';
php > var_export($my_array);
array (
0 => 'one',
1 => 'two',
2 => 'three',
)
php > $my_associative_array = array('first' => 'one', 'second' => 'two', 'third' => 'three');
php > var_export($my_associative_array);
array (
'first' => 'one',
'second' => 'two',
'third' => 'three',
)
php > $my_confusing_mess = array('one', 'second' => 'two', 'three');
php > var_export($my_confusing_mess);
array (
0 => 'one',
'second' => 'two',
1 => 'three',
)
php >
[/code]
I get the feeling i could have placed both items in a single associative array, with the timestamps as keys, and then sorting the array by keys. But I'm not sure how I would have done that, because I still don't quite understand how keys work, or what the => operator actually means.[/quote]You are right, you can use the unix time as a key as well. The code in my first posting needs minor modificatins to do so:
<i>
</i> // filemtime is the key
// right to the equality sign is the value
// which is another array in this case
$fi[filemtime($filepath)] = [
// timestamp is the key
// date() is the value
"timestamp" =>date("F d Y H:i:s", filemtime($filepath)),
"filename"=>$fileinfo['filename'] . "." . $fileinfo['extension'],
"filepath" =>$filepath
];
Doing it this way the array can be sorted easily without a callback funktion.$thefi = $fi[$thetimestamp]
However the keys of the array will not be continuous, therefore it is not possible to loop through this array by a simple for loop. You need to use foreach: foreach($fi as $time=>$data) {
echo $data['filename'] . ' taken at ' . $data['timestamp'];
}
Wouldn't using the timestamp as a key mean multiple files with the same timestamp would get overwritten?[/quote]Yes, this is true and this is one reason why I didn't choose this procedure in my first posting.
it might be better if a simple increment number was used as the key ($number++), and then add the raw timestamp integer as an associated element.[/quote]Now we are back at the code in my first posting: Incrementing the key can be done automatically by omitting the index when adding a record:
$fn[] =
usort($fi, function($a, $b)
{
return ($a['time'] - $b['time']);
});
>@PeterPan_321#1598121 [root](https://www.webdeveloper.com/forum/d/383007/15) - I still don't quite understand keys yet, which is why I'd asked for an example of associative array. Maybe ALL arrays in PHP are associative in the background? I don't know,, but given I was starting by getting each image's fullpath into a $filepaths array, and storing each file's timestamps in a separate $timestamps array, From what you said, I get the feeling i could have placed both items in a single associative array, with the timestamps as keys, and then sorting the array by keys. But I'm not sure how I would have done that, because I still don't quite understand how keys work, or what the => operator actually means. I can keep trying, but an example would be appreciated. I realize its something I really need to learn, but I'm having trouble grasping how it works from the online MANual or other examples I've seen.
but on on the 'timestamp' element rather than the key. Is that possible?[/quote]Yes, this is possible: If you do not intend to sort by key but by the element 'timestamp' inside the data you need to use usort() and a callback function as pointed out in my previous posting.
>@PeterPan_321#1598202 . If I move to associative arrays for this little project and let timestamps be my keys
time()
$arrayData = array( 123456789 => "something happened",
123499876 => "something else happened",
123698789 => "and something else happened");
>@root#1598207 Ireally don't think you fully understand arrays.
> KEYS are the ASSOCIATIVE array element, NUMERIC arrays are in their own right an associative array as the array position = the key, the value of the element is that property associated with the key.
>
> time() = 12345566789
> So its NUMERIC compared to "2018-10-21T12:34:56.789"
> of should I put it in a format that you might recognise...
>
> $arrayData = array( 123456789 => "something happened",
> 123499876 => "something else happened",
> 123698789 => "and something else happened");
> and the PHP time() function outputs an integer number that is UNIQUE!!!
DIM x$[4] // Basic
$x = array() // PHP
x = new Array() // JavaScript
x$[5] = 99;
$x[6] = "z";
x[4] = "a";
$x = time();
$myArrayEntry[ $x ] = "Something happened now"; // with time ref as a numeric
$myArrayEntry[ "{$x}" ] = "Something happened now"; // with time ref as a string
Here's a yes/no question: can an associative array also be referenced by position? For the above, could array position 0 (or $arraydata[0] ) be used to reference the key 123456789 and the string "something happened? in a for() loop with positional indexes?[/quote]
0.1.9 — BETA 4.26