Image Rotation via JavaScript, AJAX, and PHP
Download zip file with documentation
This script came about via a conjunction of a number of separate influences. It started with a question about how to have an image change on a page every so many seconds. As I'm trying to teach myself more about JavaScript and using AJAX techniques, I had this possibly silly idea of using an AJAX call to a PHP script to do the delays, since JavaScript does not have a built-in sleep or wait function per se, but mostly just because I wanted to see if it would work.
For a demonstration of this script in action, see this simple slide-show page.
The ImageRotator class contains everything needed to set up the requisite JavaScript code in a PHP page. All you need to do is include it into your page, instantiate it, set some values to tell it things like where your images are, and call a couple methods to output the JavaScript into your page: a <script> section within the head section of your page and an "onload" attribute within the body tag. Here's a sample usage in a simple page:
<?php
require_once "ImageRotator.php";
$rotator = new ImageRotator();
// suffixes of image files to be displayed:
$rotator->setSuffixes('PNG,png');
// directory where images are located relative to the web document root:
$rotator->setImageDir('/images');
// delay in seconds between image changes:
$rotator->setDelaySeconds(8);
// HTML img element ID attribute value of image to be rotated:
$rotator->setImageId('image');
?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang='en'>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=ISO-8859-1'>
<meta name="description" content="">
<meta name="keywords" content="">
<title>Untitled</title>
<?php
// insert the JavaScript block here
echo $rotator->getHeadJs();
?>
</head>
<body <?php
// put the onload attribute here
echo $rotator->getOnloadJs();
?>>
<h1>Image Rotator Test</h1>
<p>
<img src='/images/directory.png' alt='' id='image'>
</p>
</body>
</html>
The only other thing it needs is a very short PHP file for the delay function. It should be in the same script as the PHP page displaying the images, and called "delay.php".
delay.php
<?php /** * Delay for JavaScript AJAX call * * Delays for the amount of time called in the URL */ // max out the delay at 60 seconds $delay = min((isset($_GET['delay'])) ? abs((int)$_GET['delay']) : 8, 60); echo $delay; sleep($delay); ?>
And with no further ado, here is the ImageRotator class file.
ImageRotator.php
<?php
/**
* PHP class for creating a JavaScript image rotator
*
* Will generate the necessary JavaScript and related HTML to cause the
* selected HTML IMG element to perodically cycle through an array of
* images from a specific directory.
*
* @author Charles Reace (www.charles-reace.com)
* @version 1.0
*/
class ImageRotator
{
// User-modifiable variables:
/**
* @var string path where images are located relative to web document root
*/
var $imageDir = "images";
/**
* @var string Comma-separated list of file suffixes to display
*/
var $suffixes = " jpg,jpeg,gif,png,JPG,JPEG, GIF,PNG";
/**
* @var integer Interval in seconds between images.
*/
var $delaySeconds = 15;
/**
* @var string HTML ID of image element to be rotated
*/
var $imageId = "rotate_me";
/////////////////////////////////////////////////////////////////////
// Do not modify below this line unless you know what you're doing //
/////////////////////////////////////////////////////////////////////
/**
* Constructor
*
* Makes sure pre-defined class vars are correctly formatted
*
* @return void
*/
function ImageRotator()
{
$this->imageDir = trim(trim($this->imageDir), '/');
$this->suffixes = preg_replace('/\s*,\s*/', ',', trim($this->suffixes));
$this->delaySeconds = (int) abs($this->delaySeconds);
}
/**
* setter for the $imageDir parameter
*
* @param string $dir directory path relative to web document root
* @return boolean TRUE on success, else FALSE and generates user_warning
*/
function setImageDir($dir)
{
$dir = trim(trim($dir), '/');
if(!is_dir($_SERVER['DOCUMENT_ROOT'].'/'.$dir))
{
user_error("'$dir' is not a directory or is not readable.");
return(FALSE);
}
if(!is_readable($_SERVER['DOCUMENT_ROOT'].'/'.$dir))
{
user_error("'$dir' is not readable.");
return(FALSE);
}
$this->imageDir = $dir;
return(TRUE);
}
/**
* setter for the $suffixes parameter
*
* @param string $suffixes comma-separated list of file suffixes
* @return boolean Always returns TRUE
*/
function setSuffixes($suffixes)
{
$this->suffixes = preg_replace('/\s*,\s*/', ',', trim($suffixes));
return(TRUE);
}
/**
* setter for the $delaySeconds parameter
*
* @param integer $delay delay in seconds
* @return boolean Always returns TRUE
*/
function setDelaySeconds($delay)
{
$this->delaySeconds = (int) abs($delay);
return(TRUE);
}
/**
* setter for the $imageId parameter
* @param string $id HTML ID
* @return boolean Always returns true
*/
function setImageId($id)
{
$this->imageId = trim($id);
return(TRUE);
}
/**
* get an array of image pathnames
*
* @return array array of file pathnames relative to web document root
*/
function getImageArray()
{
$images = array();
$cwd = getcwd();
chdir($_SERVER['DOCUMENT_ROOT']);
$images = glob($this->imageDir.'/*.{'.$this->suffixes.'}', GLOB_BRACE);
chdir($cwd); // back to original directory
return($images);
}
/**
* get the JavaScript text for the head section
*
* @return string A javascript element and code to be inserted within the
* head section of a [X]HTML page
*/
function getHeadJs()
{
$images = $this->getImageArray();
if(!count($images))
{
return(FALSE);
}
$js = <<<EOD
<script type="text/javascript">
/*
* AJAX function to provide delay functionality
*/
function ajaxFunction(ix, id, url)
{
/* usual stuff to create xmlHttp object */
var xmlHttp;
try
{
// Firefox, Opera 8.0+, Safari
xmlHttp=new XMLHttpRequest();
}
catch (e)
{
// Internet Explorer
try
{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{
alert("Could not display some data as your browser does not support AJAX.");
return false;
}
}
}
/* when data received, call image update function */
xmlHttp.onreadystatechange=function()
{
if(xmlHttp.readyState==4)
{
changeImage(ix, id, url);
}
}
/* Send request */
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
}
/*
* Change the image src value
*/
function changeImage(ix, id, url)
{
var images = new Array([<IMAGES>]);
if(images.length == 0)
{
return false;
}
if(ix >= images.length)
{
ix = 0;
}
document.getElementById(id).src = '/' + images[ix];
ix = ix + 1;
ajaxFunction(ix, id, url);
}
</script>
EOD;
$js = str_replace('[<IMAGES>]', "'".implode("','", $images)."'", $js);
return($js);
}
/**
* get the JavaScript for the body tag onload attribute
*
* @return string the onload string, including the "onload=" part
*/
function getOnloadJs()
{
$url = dirname($_SERVER['SCRIPT_NAME']) . '/delay.php?delay=' .
$this->delaySeconds;
return("onload='changeImage(0, \"{$this->imageId}\", \"$url\");'");
}
}