Array question

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
db579
Forum Commoner
Posts: 37
Joined: Sun Jul 18, 2010 6:23 pm

Array question

Post by db579 »

I have an array of files with each file being mapped to the date it was created. I want to introduce a 3rd 'keyid' column so that I can order the array by date selected and return the first x files easily. Is there a particular function I should be looking at for this or is my approach fundamentally wrong in some way?

This is the code it relates to:

Code: Select all

<?php

$keyid=1;

$Albums = glob("gallery/*");

foreach ($Albums as $album){
$Pictures = glob("$album/*_th.jpg");

foreach($Pictures as $picture){
$time = filemtime($picture);
$picture_array = array($time => $picture);

while($keyid<=10)
  {
  echo $picture_array[$keyid];
  $keyid++;
  }
}
				
}

?>
Thanks very much for any help!
cpetercarter
Forum Contributor
Posts: 474
Joined: Sat Jul 25, 2009 2:00 am

Re: Array question

Post by cpetercarter »

I don't think that

Code: Select all

$picture_array[$keyid]
will return what you want. You have constructed the array $picture_array with Unix timestamps as the keys and the names of the picture as the values. If you want the ten most recent pictures, you could sort the array (or, more strictly, you could use rsort() so that the highest timestamp is first), then array_slice() (to isolate the top ten pictures) and then iterate through the sliced array with 'foreach' to display the pictures.
db579
Forum Commoner
Posts: 37
Joined: Sun Jul 18, 2010 6:23 pm

Re: Array question

Post by db579 »

Hi thanks very much for the suggestion that seems exactly what I want. I'm having trouble with the array_slice function though. Have used krsort to sort the array as I think the unix timestamp (which I want to order the array by) is the key in this case. Then I've tried using the array_slice as you suggested but it still returns all the values of the array. Could anyone see what I'm doing wrong please?

Code: Select all

$Albums = glob("gallery/*");

foreach ($Albums as $album){
$Pictures = glob("$album/*_th.jpg");

foreach($Pictures as $picture){
$time = filemtime($picture);
$picture_array = array($time => $picture);

krsort($picture_array);

$top_ten = array_slice($picture_array,0,10,true);
print_r($top_ten);
}
}
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: Array question

Post by AbraCadaver »

Depends upon if you want a top ten array for each album or the top ten from all albums:

Top ten per album (you'll have an array of albums that each contain an array of the top ten):

Code: Select all

foreach(glob("gallery/*") as $album){
        $picture_array = array();
	foreach(glob("$album/*_th.jpg") as $picture){
		$time = filemtime($picture);
		$picture_array[$time] = $picture;
	}
	krsort($picture_array);		
	$top_ten[$album] = array_slice($picture_array,0,10,true);
	print_r($top_ten);
}
This should do a top ten overall:

Code: Select all

foreach(glob("gallery/*") as $album){
	foreach(glob("$album/*_th.jpg") as $picture){
		$time = filemtime($picture);
		$picture_array[$time] = $picture;
	}
}
krsort($picture_array);		
$top_ten = array_slice($picture_array,0,10,true);
print_r($top_ten);
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
db579
Forum Commoner
Posts: 37
Joined: Sun Jul 18, 2010 6:23 pm

Re: Array question

Post by db579 »

Thanks AbraCadaver this does give me a top ten as I wanted. If printed the array returns the top ten files with their unix timestamps. According to this the ten most recent files are indeed returned (i.e. the ten timestamps returned are chronological) but this isn't actually the case.

I upload files using filezilla so I expected that when I uploaded a folder with ten or more items in it all the files returned by this script would be from that most recent folder but this isn't the case (some files returned are from most recent folder but with 2 or 3 exceptions). Any idea why this is? I'm not sure if the problem is with my foreach loops or with my use of the filemtime function.

This is my code:

Code: Select all

foreach(glob("gallery/*") as $album){
        foreach(glob("$album/*_th.jpg") as $picture){
                $time = filemtime($picture);
                $picture_array[$time] = $picture;
        }
}

krsort($picture_array);   
  
$latest = array_slice($picture_array,0,10,true);

print_r($latest);
Thanks very much for the help!
db579
Forum Commoner
Posts: 37
Joined: Sun Jul 18, 2010 6:23 pm

Re: Array question

Post by db579 »

Also the array $picture_array doesn't seem to contain every file anymore, printing it only outputs about 25 there should be a couple of hundred? Would be grateful if anyone could help me out!
cpetercarter
Forum Contributor
Posts: 474
Joined: Sat Jul 25, 2009 2:00 am

Re: Array question

Post by cpetercarter »

I don't know exactly why you are having these problems. However, relying on filemtime() can lead to unexpected results (it is the time the file was last modified, not the time the picture was uploaded). If I wanted to manage several hundred pictures, I would use a database to store information about them. A database would be more reliable and flexible than your present approach. You can store the information you want and extend it and search it in all sorts of ways.
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: Array question

Post by AbraCadaver »

The problem lies here:

Code: Select all

$picture_array[$time] = $picture;
Array keys must be unique, so if there are 10 files with the same timestamp then only the last one added to the array will be there. You might try using this instead:

Code: Select all

$picture_array[$picture] = $time;
Then you would use rsort() instead of krsort().
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
db579
Forum Commoner
Posts: 37
Joined: Sun Jul 18, 2010 6:23 pm

Re: Array question

Post by db579 »

Unique key ids does seem to be a problem which brings me back to my original question. Is it possible/how could I have an array with two columns (timestamp and filename) and a third column for unique key ids, where the array could be sorted by timestamp?

Code: Select all

$picture_array[$picture] = $time;
Just gives me the timestamp and an id the filename is lost.

I realise databases could be used but I've only ever used MySQL with PHPmyadmin and don't have that now (I'm not even sure if the host has MySQL installed) so was hoping it could be done this way.

Thanks for the help!
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: Array question

Post by AbraCadaver »

I'm losing it, sorry. The problem is with rsort(). You need to use arsort().
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
db579
Forum Commoner
Posts: 37
Joined: Sun Jul 18, 2010 6:23 pm

Re: Array question

Post by db579 »

Sorry, I'm a bit confused - why is the problem with the sorting? Have tried using arsort but think I want asort to have it in order of newest first. Either way though, it doesn't solve the fact that only some files are stored in the array (presumably because of the unique keyid thing?).

Thanks very much for you continued help!
db579
Forum Commoner
Posts: 37
Joined: Sun Jul 18, 2010 6:23 pm

Re: Array question

Post by db579 »

Oh sorry, realise what you meant now. Have modified my code to use arsort now and printing the array does give me the array I want. The only problem now is that the filenames are the keyids rather than the values (unless I'm mistaken?). I'm trying to loop through the array using a foreach statement but obviously it now loops through the timestamps rather than the filenames. How do I specify that I want the foreach loop to loop through the keyids rather than the values?

This is the code as it currently is if that helps:

Code: Select all

foreach(glob("gallery/*") as $album){
        foreach(glob("$album/*_th.jpg") as $picture){
                $time = filemtime($picture);
                $picture_array[$picture] = $time;
        }
}

arsort($picture_array);   

$latest = array_slice($picture_array,0,7,true);

foreach($latest as $latestpic){

echo $latestpic;
}
Thanks very much!
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: Array question

Post by AbraCadaver »

Code: Select all

foreach($latest as $file => $time) {
   echo $file;
}
Or:

Code: Select all

foreach(array_keys($latest) as $file) {
   echo $file;
}
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
db579
Forum Commoner
Posts: 37
Joined: Sun Jul 18, 2010 6:23 pm

Re: Array question

Post by db579 »

Perfect! Thanks very much, really appreciate the time and effort!
Post Reply