My shared server is running PHP Version 5.4.28
I just noticed my random image script isn't random on page change. It's stuck on the same image on all pages running the script in all major browsers.
What happened?
I'm using the code below:

<?php


$folder = '.';


/*	

            <img src="http://example.com/img.php">


You can also serve up random HTML files:

    $extList['html'] = 'text/html';
    $extList['htm'] = 'text/html';
*/

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


$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 ("Cannot initialize new GD 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);
	}
}

?>

    I think your problem is that the browser thinks it's getting the same image(<img src="img.php"> so it's using the cached version that it's already stored.

    To test this, hold down shift while clicking refresh. If you get a new image, then that's your issue.

    to stop this from happening, you could do something as simple as attaching a random string or timestamp behind the filename:

    <img src="http://example.com/img.php?21345">

    This should trick the browser into thinking it's never seen the filename before.

      You could also serve headers to (hopefully) prevent the output from being cached. Below shamelessly stolen from my own code 😛

      header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
      header("Cache-Control: post-check=0, pre-check=0", false);
      header("Pragma: no-cache");
        Derokorian;11046073 wrote:

        You could also serve headers to (hopefully) prevent the output from being cached. Below shamelessly stolen from my own code 😛

        header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
        header("Cache-Control: post-check=0, pre-check=0", false);
        header("Pragma: no-cache");

        I'm probably wrong about this, but I thought that might not be a good resolution unless there's a small amount of content getting passed on the page.

          schwim;11046079 wrote:

          I'm probably wrong about this, but I thought that might not be a good resolution unless there's a small amount of content getting passed on the page.

          His script only outputs an image. I use these exact headers for my captcha, for the same reason - to prevent caching of said image.

            I had assumed that the file was being included in another file. If that's the case, wouldn't the headers have to be passed by the parent file or can headers be passed for included files as well?

              I added mt_rand() and getting <img src="img/footer/img.php?325477509"> so it's working.
              However, I was hoping the code I initially posted that sits in the image's folder could be modified because there are literally hundreds of php pages with <img src="img/footer/img.php"> in them.

                If you're calling img.php from other files, you're deffo going to have to change the files calling because you can't modify headers once any html is output but this issue should really be trivial.

                Open all the files in your editor of choice, find and replace in all files. mt_rand should work just fine.

                  schwim;11046083 wrote:

                  I had assumed that the file was being included in another file. If that's the case, wouldn't the headers have to be passed by the parent file or can headers be passed for included files as well?

                  It depends from where you pass the headers&#8230;

                  If you pass the headers from the page containing the image element, then the headers relate to that page. If you pass the headers from the script serving the image(s), then the headers relate to those images.

                  But you might be better off randomly generating the image src with distinct cacheable URIs for each image and forgo your image serving script.

                  image-page.php

                  <?php
                  $i = mt_rand(0, 6); // 7 images, called 0.jpg ... 6.jpg
                  
                  ?>
                  <img src="/images/<?php echo $i; ?>.jpg">
                  

                    I think the modern browsers only run the script once and you'll get the same cached image on any page running it.

                      I think he's telling you that you could echo out the image code in img.php. Instead of wrapping that file in an img tag, you'd include it via php and have it build the img tag when included.

                        I can see where his code would build a different link but I've gif, jpg, and png in the image folder. That would just display one file type.

                          You would obviously have to generate filenames of files that are actually there&#8230; Doesn't matter if they are called a.png or 1.jpg - you still need to generate matching names and the principle is identical regardless of image mime type and/or file ending

                            4 days later

                            What would the code look like?
                            Maybe I could understand it.
                            Thanks

                              Well, your current solution
                              1. A request for a random image is sent (from the img element to some php script)
                              2. The php script somehow retrieves a random image (which is done through... its filename? some other unique identifier?)

                              And the process of pre-generating a random image would be
                              1. somehow retrieve a unique identifier of a random image
                              2. put this unique identifier into the src attribute of the img element so that it will match that image when requested

                                Write a Reply...