通过PHP随机化目录中的照片

I have the following code that is functional that will randomize the photos I have in my 'photos' folder each time the refresh button is clicked. I know this may not be the most efficient way for this to be coded but for my matter it works. I am looking for help regarding my PHP code that will make the photos more random. I currently have 200+ pictures in the folder and often get repeated pictures more than I'd like. What changes to it can I make? (PS. ignore the AJAX/JavaScript I was playing around with)

<html> 

<head> 
<title>Pictures!</title> 
    <style type="text/css">
    body{ background-color:D3DFDE; }
    </style>
    <script type="text/javascript"      src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
</head> 
<body> 
<div id='main'>
<?php 
function randomimages(){ 
    $dirname = isset($_REQUEST['dir'])? $_REQUEST['dir'] : './photos/'; 
    $numimages = isset($_REQUEST['num'])? $_REQUEST['num'] : 1; 
    $pattern = '#\.(jpg|jpeg|png|gif|bmp)$#i'; 
    $files = array(); 
    if($handle = opendir($dirname)){ 
        while(($file = readdir($handle)) !== false){ 
            if(preg_match($pattern, $file)){ 
                array_push($files, "<center><img src='" . $dirname . $file . "' alt='' /></br><br/><hr/></center>"); 
            } 
        } 
        closedir($handle); 
        shuffle($files); 
    } 
    return implode("<center><br/>", array_slice($files, 0, $numimages)) . "<br/> </center>"; 
} 
?>
<!-- <center><a id="myButton" href="#">MAS PICTURES!</a></center> -->
<center><input type='button' onClick='window.location.reload(true)' value='MAS PICTURES!!!' style="height:200px; width:150px" /></center>
<hr/>
<script type="text/javascript">
        $(function() {
      $("#myButton").click(function() {
        $("#main").load("index.php");
      });
    });
</script>
<?php echo randomimages(); ?>
<center>Created by: Matt & Joe</center>
</div>


</body> 
</html>

You can do the following:

  1. Optimize the code by not reading the directory over and over. What you can do this by reading the directory once (and say then store the entries as an array in APC cache). Set a timeout for this APC key to bust the cache once in a while.
  2. Call the `mt_rand` function with min as `0` and max as `count(array)-1` and access that index.

Generic code to read from directory can be as follows (needs modification to match your needs):

<?php
function &list_directory($dirpath) {
    if (!is_dir($dirpath) || !is_readable($dirpath)) {
        error_log(__FUNCTION__ . ": Argument should be a path to valid, readable directory (" . var_export($dirpath, true) . " provided)");
        return null;
    }
    $paths = array();
    $dir = realpath($dirpath);
    $dh = opendir($dir);
    while (false !== ($f = readdir($dh))) {
        if (strpos("$f", '.') !== 0) { // Ignore ones starting with '.'
            $paths[] = "$dir/$f";
        }
    }
    closedir($dh);
    return $paths;
}

Provide the directory full path to the variable $dirpath

$image_source_array=scandir($dirpath);
sort($image_source_array);

Use mt_rand function with min as 0 and max as count($image_source_array)-1 and access that index from the array to get the image name

and then access the image with the $dirpath/image name you will get the random image each time

Create function like this it will be the shortest approch

function randomimages() {
    $dirname = isset($_REQUEST['dir']) ? $_REQUEST['dir'] : './photos/';
    $image_source_array = scandir($dirname);
    sort($image_source_array);
    $image_count = count($image_source_array) - 1;
    $rand_index = mt_rand(3, $image_count);
    //Starting with 3 because scandir returns directory also in the 2 indexes like '.' and '..'
    $rand_image_path = $dirname . $image_source_array[$rand_index];
    return $rand_image_path;
}

For the sake of simplicity and reusability, you might want to use RegexIterator together with DirectoryIterator:

function randomimages($path, $num_images)
{
    $images = array();

    foreach (new RegexIterator(new DirectoryIterator($path),
                               '#\.(jpe?g|gif|png|bmp)$#i') as $file) {
        $images[] = $file->getPathname();
    }

    shuffle($images);

    return array_slice($images, 0, $num_images);
}

Using:

$path = isset($_REQUEST['dir']) ? $_REQUEST['dir'] : './photos/';
$num_images = isset($_REQUEST['num']) ? $_REQUEST['num'] : 1;

print implode('<br />', randomimages($path, $num_images));