What is the best way to sort dates using filemtime() from oldest to most recent?
[RESOLVED] Sorting dates with filemtime()
It should return a timestamp as an integer. The larger the integer, the later the date...
Chris
oh okay...didn't know if I had to use some kind of date format. So basically after it returns the timestamp then just use the sort() right?
as dinger suggested, spool the directory into an array and then sort the array. Use the timestamps as the values (not the keys). Files with the identical modification times with cancel each other out in the array if used as keys:
<?
$handle = opendir ('.');
while (($filename = readdir ($handle)) !== false)
{
if ($filename != '..' && $filename != '.')
{
$file_array[$filename] = filemtime ($filename);
}
}
asort ($file_array);
echo '
Directory sorted by date:<br><br>
<table border=0 cellspacing=0 cellpadding=5>
';
foreach ($file_array as $key => $value)
{
echo '<tr><td>' . $key . '</td><td>' . date ('Y-m-d h:i:s', $value) . '</td></tr>';
}
echo '
</tr>
</table>
';
?>
I am doing something similiar to that but I'm using a 2-dimensional array to store the names of the files and also their date of modification. So how would I sort this array by date and not by the name. This is how my array is set up
function grabImages($name)
{
$i = 0;
if ($handle = opendir('whatever/html/gallery/'.$name))
{
while (false !== ($file = readdir($handle)))
{
if ($file != "." && $file != "..")
{
$images[$i][0] = $file;
$tmp_file = $images[$i][0];
$images[$i][1] = filemtime($tmp_file);
$i++;
}
}
closedir($handle);
return $images;
}
else
echo "Couldn't open directory";
}
I might be wrong setting my array up like that too...not sure.
is there a specific reason why you are doing a 2D array like that? if you must do it that way then you can then loop thru your 2D array and create the orginal array I suggest for sorting purposes.
...the only reason I'm using a 2D array is because that was the first that popped into my head to do it that way. I need those two pieces of info in one variable so I can pass it all back to the calling function. If there's a better way please let me know.
that's my point. You need to store 2 pieces of info in each array index: 1)the name of the file 2)the modification date of the file. A regular 1D array is all you need because have the 2 place holders: 1)the key 2)the value. your method is adding a 3rd part to the equation with the incrementing interger ($i). This seems like an unecessary piece of info but then I don't know the larger aspects of your app, perhaps you need it for some other reason.
I think I'm a little confused. All I need is an array that will hold the filename and it's modified date. Then I need to sort the array by the date so I can display the images using their filename and order them by their date.
...then take a look at the original code snippet i posted before.
How does this store the filename and the date when its only a one dimensional array tho?
$file_array[$filename] = filemtime ($filename);
It is a one dimensional array. The filename is the array key and the last modified time is the value.
Chris
I guess I don't understand what key's and values are...well...I know what values are just not keys. Does php.net have a page about what keys are?
you should really read up on arrays:
http://www.php.net/manual/en/language.types.array.php
A key is the value that goes inside the [] in the variable name.
If using a standard array (and in most programming languages) these are integers starting with 0.
However, in PHP the key can be any value.
for example, an array containing the prices of fruit might contain:
$price['apple'] = 0.75
$price['orange'] = 0.99
$price['lemon'] = 0.57
where 'apple', 'orange' and 'lemon' are the keys and .75. .99 and .57 are the values.
In your case the filename would go in the brackets:
$file_array[$filename] = filemtime ($filename);
Thus, you would access the integer timestamp of the last modified date of the file "/path/to/my/file' like this:
$file_array['/path/to/my/file'];
it would be similar to accessing an array in any other language:
$file_array[0] = time();
$file_array[1] = time() - 50;
However, instead of using an integer as the key, you are simply using the filename.
Then, as devinemke suggested, you can access the keys of the array with the following code:
foreach ($file_array as $key => $value)
{
echo '<tr><td>' . $key . '</td><td>' . date ('Y-m-d h:i:s', $value) . '</td></tr>';
}
This stores the key in the variable $key and the last modified date in the variable $value. It then echos this information in a nice format.
This is what they call an associative array (or, in some languages, a hash), as each key is associated with one value (i.e. in this case each filename is associated with one last modified date).
I gather that it could be looked at as a two dimensional array in a sense that you do have two sets of data which are associated with each other. However, by using an associative array, it ensures that the filename and last modified date stay together as a pair during the sorting process.
If using a 2-D array it is possible for the pairs to get jumbled, and then you would end up with files with incorrect last modified dates, which is not what you want.
Chris
Okay now I totally understand
I've been so used to only using numbers for the key. The only thing I don't quite understand fully is why you use the function foreach(). I'm thinking right now that might be the only way to echo a key or grab the key instead of its value. Not sure if its possible to do that without the foreach().
I'll take a look on PHP.net and see if I can figure what that does exactly.
On this line
$images[$file] = filemtime ($file);
I get this error...
Warning: filemtime() [function.filemtime]: Stat failed for Save0001.jpg (errno=2 - No such file or directory)
Here's the whole thing...
function grabImages($name)
{
$images = array();
if ($handle = opendir('path/html/gallery/'.$name))
{
while (false !== ($file = readdir($handle)))
{
if ($file != "." && $file != "..")
{
$images[$file] = filemtime ($file);
}
}
closedir($handle);
asort ($images);
return $images;
}
else
echo "Couldn't open directory";
}
your getting that error because filemtime() if called from another directory needs a full path (not just a filename). I suggest the following fix:
function grabImages($name)
{
$images = array();
$path = 'path/html/gallery/';
if ($handle = opendir($path . $name))
{
while (false !== ($file = readdir($handle)))
{
if ($file != "." && $file != "..")
{
$images[$file] = filemtime ($path . $file);
}
}
closedir($handle);
asort ($images);
return $images;
}
else
echo "Couldn't open directory";
}
Just a note to people trying to display files in a directory with the latest modified file at the top of the list.
Use the arsort() method instead of the asort().
Took me a while to realise this, so thought i'd post it on here.
Hi I tried using your code, pretty much cut and pasted with the exception of the first line, I added the sub-folder of the files.
I get the same date time (1969-12-31 04:00:00) for all files but the last one.
this is the link
http://steinbauer.com/temp/test.php
this is the code:
$folder = 'images/';
$handle = opendir ($folder);
while (($filename = readdir ($handle)) !== false)
{
if ($filename != '..' && $filename != '.')
{
$file_array[$filename] = filemtime ($filename);
}
}
asort ($file_array);
echo '
Directory sorted by date:<br><br>
<table border=0 cellspacing=0 cellpadding=5>
';
foreach ($file_array as $key => $value)
{
echo '<tr><td>' . $key . '</td><td>' . date ('Y-m-d h:i:s', $value) . '</td></tr>';
}
echo '
</tr>
</table>
';
As I mentioned sorry if this is actually a no-brainer--but that's where I am at the moment.