tronjavolta
tronjavolta

Reputation: 757

php script to show 4 random photos from a folder is showing the same photo 4 times

i'm trying to build a little module for a site that pulls 4 random photos from a folder on the server and presents them in a div. what's happening is the same 4 photos are being called. how do i get it to call 4 different photos?

heres the random.php file:

<?php
$folder = '.';

$extList = array();
$extList['jpg'] = 'image/jpeg';
$extList['jpeg'] = 'image/jpeg';

$img = null;

if (substr($folder,-1) != '/') {
$folder = $folder.'/';
}

if (isset($_GET['img'])) {
$imageInfo = pathinfo($_GET['img']);
if (
    isset( $extList[ strtolower( $imageInfo['extension'] ) ] ) &&
    file_exists( $folder.$imageInfo['basename'] )
) {
    $img = $folder.$imageInfo['basename'];
}
} else {
$fileList = array();
$handle = opendir($folder);
while ( false !== ( $file = readdir($handle) ) ) {
    $file_info = pathinfo($file);
    if (
        isset( $extList[ strtolower( $file_info['extension'] ) ] )
    ) {
        $fileList[] = $file;
    }
}
closedir($handle);

if (count($fileList) > 0) {
    $imageNumber = time() % count($fileList);
    $img = $folder.$fileList[$imageNumber];
}
}

if ($img!=null) {
$imageInfo = pathinfo($img);
$contentType = 'Content-type: '.$extList[ $imageInfo['extension'] ];
header ($contentType);
readfile($img);
} else {
if ( function_exists('imagecreate') ) {
    header ("Content-type: image/png");
    $im = @imagecreate (100, 100)
        or die ("Can't initialize image stream");
    $background_color = imagecolorallocate ($im, 255, 255, 255);
    $text_color = imagecolorallocate ($im, 0,0,0);
    imagestring ($im, 2, 5, 5,  "IMAGE ERROR", $text_color);
    imagepng ($im);
    imagedestroy($im);
}
} 

?>

here's how random.php is being called:

<?php

/* DATA */
$data = array(
array('COUNT', '88', 'Here are a few of them', '1, 2, 3, 4'),
);
?>

<div>
<table class="reop"  border='0' width='100%'  cellpadding='0' cellspacing='10'>

<?php
$count = 0;
foreach($data as $row) {
    $class = ($count % 2 == 1 ? " class='alt'" : '');
    echo "<tr$class>";
    for($j = 0; $j < count($row); $j++) {
        if ($j!=3) {
            echo "<td class='cell_$j'>$row[$j]</td>";
        } else {


 //           $avatar = ''; 
            $array = preg_split('/,/', $row[$j], -1, PREG_SPLIT_NO_EMPTY);
            foreach ($array as $val) {
            $avatar .= '<img src="/staffpics/random.php"> ';
            }   
            echo "<td class='cell_$j'>$avatar</td>";

        }   

    }   
    echo '</tr>';
//    $count++;
}   

?>  

</table>

Upvotes: 0

Views: 1954

Answers (3)

Kaii
Kaii

Reputation: 20540

when your page is displayed, most browsers will immediately request the four pictures.. nearly all at the same time. your code for "random" picking a picture is based on time() which returns a count of seconds since the begin of unixtime. executed 4 times within the same second it will also yield the same result 4 times.

your code:

$imageNumber = time() % count($fileList);
$img = $folder.$fileList[$imageNumber];

should be rewritten as:

// filelist starts with "0", count with "1" .. so we are off-by-one and first picture would never show without -1
$imageNumber = rand() % (count($fileList) - 1);
$img = $folder.$fileList[$imageNumber];

that way you will get "random" pictures.

Also, what Mister Lister commented is totally valid - your browser may also cache the picture and thus only request a picutre once and just display that one again and again using its cache.

to avoid this, replace any <img src="random.php"> with <img src="random.php?rand=<?= rand(); ?>">


But note:

your server may eventually return the same random number multiple times so eventually (rarely) you will end up with the same picture twice on the same page.

to fix that, you must completely rewrite your code.

the script rendering the page should decide which pictures to choose and ensure that no picture is displayed twice instead of just including a "give random picture" script, which is independent of the page rendered.

much easier, you could try this:

// find all images - case SenSItivE
$all_images = glob("/path/to/images/*.{jpeg|jpg|png|gif}", GLOB_BRACE);
// bring array in random order
shuffle($all_images);
// pick four random images - you may also use a for or foreach loop to iterate the array
list ($img1, $img2, $img3, $img4) = $all_images; 
// write code to display four images here

Upvotes: 2

Nazariy
Nazariy

Reputation: 6088

Here is another way of fetching 4 random photos:

//randomize order
shuffle($fileList);
//get first 4 values of array
$randomPhotos = array_slice($fileList, 0, 4);

Please note, shuffle would change value order in your original array.

Upvotes: 1

user229044
user229044

Reputation: 239301

Call srand to seed your random number generator.

Upvotes: 0

Related Questions