Build a PHP Multiple Picture Showcase Using PHP and HTML
I recently decided to create a showcase for one of my sites. I needed a row of five thumbnail images of my products, randomly displayed. I thought it would be easy to find this PHP code, but this turned out not to be the case, so I rolled up my sleeves and wrote my own. The result is a new way (at least, to me) of rotating images — I hope you’ll find it as useful as I did.
The problem was that I didn’t really want a random display. I wanted random, but without duplicates. I had about 25 images, so the chance of repeat images in a row of five was pretty good — and would be pretty unprofessional!
To further complicate the situation, I wanted to avoid using a PHP page (which would have simplified things immensely), and instead, call a PHP script from within my HTML code, something like this:
<img src="mysite.com/rotate.php?i=0" />
<img src="mysite.com/rotate.php?i=1" />
<img src="mysite.com/rotate.php?i=2" />
Using a parameter like '?i=0'
provides a way to distinguish the calls from one another. It will be the key to avoiding duplicate images.
An Easy Solution: a PHP Page
If I was to use a PHP page, the code would be extremely simple: just take an array of image URLs, shuffle that array, then ‘deal them out’, displaying entry 0 first, then 1, then 2, and so on, like this:
<?php
// display a series of random images - PHP form solution
// (c) 2004 David Pankhurst - use freely, but please leave in my credit
$images=array( "img1.gif","img2.gif","img3.gif","img4.gif","img5.gif" );
srand(time());
shuffle($images);
for ($i=0;$i<5;++$i) // display my five images
echo "<a href='$images[$i]'>image $i</a><br>";
?>
But, as I needed occasionally to use an HTML form instead of PHP, I decided a PHP call from within an HTML page would be better, though this made the problem harder to solve.
The reason is that the code above is all done at once. Requests to PHP scripts are largely stateless (barring PHP sessions, which are impractical in this instance). This makes it difficult to call a script five times (once for each image), and get the same ‘state’ (shuffled order) back. But the alternative was for the images to be completely random, in which case I’d end up with duplicates.
The Better Option: srand()
To solve this problem, I used a solution much like that shown above for a single PHP script: I created a shuffled array. But this time I used the query string parameter passed (i=0, i=1, etc.)
as the index to the array, to determine which picture to display.
To keep this array stable between calls, I needed a pseudo-random value, which was provided by PHP and its seeded random function, srand()
.
PHP’s random numbers, although random enough for most uses, are not random at all — they’re based on a seed value. This means that, if you use the same seed value each time, the sequence of ‘random’ numbers it generates will be the same. This repeatability made this function ideal for my needs, which included a shuffled image list that stayed the same for long periods of time. By seeding with the same number each time, and shuffling the list with those numbers, my array would be in the same ‘random’ order each time.
In this case, I used time()
as the seed value for each call. Dividing it by 10 gave me a seed value that changed once every ten seconds, which meant that the array would stay shuffled in the same order for 10 seconds at a time.
The result is that the array appears random, but the order stays static long enough for the five PHP calls to occur — each selecting a different image from the list.
Here’s the new code:
<?php
// rotate images randomly but w/o dups on same page - format:
// <img src='rotate.php?i=0'> - rotate image #0 - use 'i=1'
// for second, etc
// (c) 2004 David Pankhurst - use freely, but please leave in my credit
$images=array( // list of files to rotate - add as needed
"img1.gif",
"img2.gif",
"img3.gif",
"img4.gif",
"img5.gif" );
$total=count($images);
$secondsFixed=10; // seconds to keep list the same
$seedValue=(int)(time()/$secondsFixed);
srand($seedValue);
for ($i=0;$i<$total;++$i) // shuffle list 'randomly'
{
$r=rand(0,$total-1);
$temp =$images[$i];
$images[$i]=$images[$r];
$images[$r]=$temp;
}
$index=(int)($_GET['i']); // image index passed in
$i=$index%$total; // make sure index always in bounds
$file=$images[$i];
header("Location: $file"); // and pass file reference back
?>
The shuffle()
function has now been replaced by my own shuffle loop, partly because I wasn’t happy with the output of shuffle()
in this case, and partly because I wanted to make sure ‘my’ list of random numbers was always used to shuffle the array (the key to keeping it repeatable).
Using The Code in Your Application
To use this code, you’ll need to do the following:
- Replace the entries in
$images
with your own (including the path as needed). - Change the
$secondsFixed
to decide for how long the list will stay the same before it’s reordered. The timeframe should be large enough to allow all the PHP calls to be made easily within the time allotted. - Upload the script, and call it from your HTML like this:
<img src='mysite.com/rotate.php?i=0'>image #1
<img src='mysite.com/rotate.php?i=1'>image #2
<img src='mysite.com/rotate.php?i=2'>image #3and so on…
Of course, if you have more calls than images in the array, it will wrap around; otherwise, you will get random, non-duplicating images.
One note: setting the $secondsFixed
value to 10 ensures that the random list reorders every ten seconds. So, if the PHP calls for a page straddle this boundary — some within a ten second boundary, some outside it — the list could still be poorly randomized. To avoid this, you can increase the value. For instance, at 3600, the list will stay the same for an hour, and it’s the rare page load that will cross that boundary exactly.
Aside from that small hitch, this is a useful PHP technique that allows me to show a randomly-selected series of images without duplicates. I’ve already placed it successfully on one of my sites, as well as a client’s eBay auction (to ‘freshen’ the display from time to time). I hope it can prove useful to you as well.