Search code examples
phprandomincludeglob

php include random file with no repeat on pageload


I am currently using mt_rand to display a random file from the specified folder each time the page is loaded.

After doing lots of searching i think i need to create an array and then shuffle the array, but not sure how to go about this.

Most of the examples i have found use an array and then echo the results where as i'm trying to include the result.

<?php
$fict = glob("spelling/*.php");
$fictional = $fict[mt_rand(0, count($fict) -1)];
include ($fictional);
?>

Solution

  • You can use session cookies to hold a random, non-repeating list of files. Actually, for security, the session cookie should only store a list of indices into an array of files.

    For example, suppose we have the following file list in an array:

    index           file
    ----------------------------
      0      spelling/file1.txt
      1      spelling/file2.txt
      2      spelling/file3.txt
      3      spelling/file4.txt
    

    We can create an array of the indices, e.g. array(0,1,2,3), shuffle them to get something like array(3,2,0,1), and store that list in the cookie. Then, as we progress through this random list of indices, we get the sequence:

    spelling/file4.txt
    spelling/file3.txt
    spelling/file1.txt
    spelling/file2.txt
    

    The cookie also stores the current position in this list of indices and when it reaches the end, we reshuffle and start over.

    I realize all this may sound a bit confusing so maybe this gorgeous diagram will help: Gorgeous Diagram

    … or maybe some code:

    <?php
    
    $fictional = glob("spelling/*.php");    // list of files
    $max_index = count($fictional) - 1;
    $indices = range( 0, $max_index );      // list of indices into list of files
    
    session_start();
    
    if (!isset($_SESSION['indices']) || !isset($_SESSION['current'])) {
    
        shuffle($indices);
        $_SESSION['indices'] = serialize($indices);
        $_SESSION['current'] = 0;           // keep track of which index we're on
    
    } else {
    
        $_SESSION['current']++;             // increment through the list of indices
                                            // on each reload of the page
    
    }
    
    // Get the list of indices from the session cookie
    $indices = unserialize($_SESSION['indices']);
    
    // When we reach the end of the list of indices,
    // reshuffle and start over.
    if ($_SESSION['current'] > $max_index) {
    
        shuffle($indices);
        $_SESSION['indices'] = serialize($indices);
        $_SESSION['current'] = 0;
    
    }
    
    // Get the current position in the list of indices
    $current = $_SESSION['current'];
    
    // Get the index into the list of files
    $index = $indices[$current];
    
    // include the pseudo-random, non-repeating file
    include( $fictional[$index] );
    
    ?>