Summary Well, your journey through the basics of HTML elements used with Ajax and PHP has come to an end with the finalizing of this chapter on images.. Therefore, when envisioning what
Trang 1//Create the thumbnail.
$func = $types[$thepath['extension']][1];
$func($dst, $filename);
?>
<img src="<?= $filename ?>" alt="" />
<p>
Change Image Size:
<a href="thumb.php?img=<?=$img?>&sml=s"
onclick="changesize('<?=$img?>','s'); return false;">Small</a>
<a href="thumb.php?img=<?=$img?>&sml=m"
onclick="changesize('<?=$img?>','m'); return false;">Medium</a>
<a href="thumb.php?img=<?=$img?>&sml=l"
onclick="changesize('<?=$img?>','l'); return false;">Large</a>
</p>
<?php
return;
} } echo "No image found.";
}
createthumb($_GET['img'], $_GET['sml']);
?>
The first function you should notice in the thumb.phpfile is setWidthHeight This function’s sole purpose is to find a properly sized set of image coordinates based on a scaled-down size In other words, it will take an image’s width and height as arguments,
as well as a maximum width and height, and then return a scaled-down width and height based on the passed-in arguments
The next function, createthumb, is a tad more complicated The createthumbfunction takes in an image path, as well as a size argument, to decide what type of image to create This particular function can have its constraints set to make a thumbnail based on the small, med, and largevariable arguments at the top of the function It will then attempt to locate the image path If the path is found, it will figure out the new size arguments (by calling the setWidthHeightfunction) and then use the appropriate image-creation func-tion based on whether the image in quesfunc-tion is a JPEG, GIF, or PNG You determine this
by using an array containing each of the image types, along with their associated GD functions for reading and writing images of that type
Once a thumbnail has been successfully created, the script will output the newly cre-ated thumbnail, and then show the same navigation as before, allowing the user to create
a new thumbnail of a different size, if necessary
Trang 2The nice thing about all of this is that it comes together in a seamless package Every-thing from uploading a new image to dynamically resizing the image is fast and efficient,
with maximum user ergonomics and very little page refreshing Desktop applications
have enjoyed such functionality for years, and I am happy to say that the Web is now a
comparable platform for such excellent interfacing Consider Figure 6-4
Figure 6-4.Dynamic image sizing—what a concept!
Summary
Well, your journey through the basics of HTML elements used with Ajax and PHP has
come to an end with the finalizing of this chapter on images You have learned how to
make images work for you in a whole new manner By making use of PHP’s advanced
scripting capabilities and Ajax’s fresh new file-loading concepts, you can now create
some very advanced and functionally sound image-based web applications
By making use of JavaScript and its XMLHttpRequestobject, you can make just about anything happen by loading server calls into a web page whenever you want It is always
important, however, to pay attention to ease of use on the user’s side of things, so
some-times adding a “Loading ” message or similar functionality can go a long way to
enhancing a user’s experience
Now that you have the basics down, it is time to start investigating some of the more advanced Ajax and PHP concepts I am a true believer that the best way to learn
some-thing is to see it in action and actually use it It is with this in mind that we move on to
the next chapter, which will encompass the concept of building a real-world
Ajax-and-PHP-based application that you can actually implement in the virtual world that is the
Internet
C H A P T E R 6 ■ I M A G E S 99
Trang 4A Real-World Ajax Application
In order to obtain a complete understanding of what goes into making Ajax-based
appli-cations, it makes sense that you should build one from scratch In order to illustrate that
process, I will lead you through the process of creating an Ajax-based photo gallery The
photo gallery is a fairly common web application that is popular among professional web
developers and hobbyists alike
The problem with something like a photo gallery is that it has all been done before
Therefore, when envisioning what I wanted to do with a photo gallery, I brainstormed
features that I would like to see implemented whenever I deploy a photo gallery, and
ways to make the gallery look different than the majority of gallery-based applications
currently on the Internet
The last aspect I considered is how to improve upon commonplace photo gallery code by using Ajax concepts There are definitely cases in which using Ajax does more
harm than good (examples of such can be found in Chapter 11), and so I wanted
some-thing that would improve upon the common gallery-viewing (and gallery-maintaining)
functionality
I wanted this gallery to remove most of the tedium otherwise involved in uploading images I find that it is time-consuming to maintain and upload images to most galleries
(the less robust ones, anyway) I wanted something I could quickly insert images into
without having to worry about resizing them I also really like the idea of seeing the
thumbnails of upcoming images before you click on them (like what you see on MSN
Spaces) That makes it more interesting to view the gallery
Since I am really against the whole uploading thing, I also set up the system so that you can simply drop a big batch of images straight into the images directory, and the
system will simply read through the directory and build the structure straight from that
If you were really interested in keeping more information on the files, it wouldn’t be too
difficult to categorize them with subfolders and use their files name for captions
I also did not want any page refreshing It is quite likely that I would plug this gallery system into a more robust application, and I didn’t want to load the rest of the
applica-tion every time I wanted to upload a new image or check out the next one Therefore, I
turned to JavaScript and Ajax to provide the required functionality
101
C H A P T E R 7
Trang 5The Code
Let’s now take a look at the code that makes up the application First, Listing 7-1 is the main script to be loaded in the browser Everything runs through this script Listing 7-2 shows the JavaScript code that is used, including running Ajax requests and updating the user interface
The remainder of the listings (7-3 through 7-7) covers the various PHP code required
to display forms, process uploads, and output images After these listings, we will look more closely at the code to see how it all works and to see the results it produces
Listing 7-1.The HTML Shell for the Photo Gallery (sample7_1.php)
<! sample7_1.php >
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" type="text/css" href="style.css" />
<title>Sample 7_1</title>
<script type="text/javascript" src="functions.js"></script>
</head>
<body>
<h1>My Gallery</h1>
<div id="maindiv">
<! Big Image >
<div id="middiv">
<?php require_once ("midpic.php"); ?>
</div>
<! Messages >
<div id="errordiv"></div>
<! Image navigation >
<div id="picdiv"><?php require_once ("picnav.php"); ?></div>
</div>
<h2>Add An Image</h2>
<form action="process_upload.php" method="post" target="uploadframe"
enctype="multipart/form-data" onsubmit="uploadimg(this); return false">
Trang 6<input type="file" id="myfile" name="myfile" />
<input type="submit" value="Submit" />
<iframe id="uploadframe" name="uploadframe" src="process_upload.php">
</iframe>
</form>
</body>
</html>
Listing 7-2.The JavaScript Required to Make the Gallery Run (functions.js)
// functions.js function runajax(objID, serverPage) {
//Create a boolean variable to check for a valid Internet Explorer instance
var xmlhttp = false;
//Check if we are using IE
try { //If the JavaScript version is greater than 5
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) { //If not, then use the older ActiveX object
try { //If we are using Internet Explorer
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) { //Else we must be using a non-IE browser
xmlhttp = false;
} } // If we are not using IE, create a JavaScript instance of the object
if (!xmlhttp && typeof XMLHttpRequest != 'undefined') { xmlhttp = new XMLHttpRequest();
} var obj = document.getElementById(objID);
xmlhttp.open("GET", serverPage);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
C H A P T E R 7 ■ A R E A L - W O R L D A J A X A P P L I C AT I O N 103
Trang 7obj.innerHTML = xmlhttp.responseText;
} } xmlhttp.send(null);
}
// Delay in milliseconds before refreshing gallery
var refreshrate = 1000;
//Function to show a loading message
function updateStatus() {
document.getElementById("errordiv").innerHTML = "";
document.getElementById("middiv").innerHTML = "<b>Loading </b>"; }
function refreshView() {
// Reload the full-size image
setTimeout ('runajax ("middiv","midpic.php")',refreshrate);
// Reload the navigation
setTimeout ('runajax ("picdiv","picnav.php")',refreshrate); }
function uploadimg(theform) {
// Update user status message
updateStatus();
// Now submit the form
theform.submit();
// And finally update the display
refreshView();
}
function removeimg(theimg) {
runajax("errordiv", "delpic.php?pic=" + theimg);
refreshView();
}
Trang 8function imageClick(img) {
updateStatus();
runajax('middiv', 'midpic.php?curimage=' + img);
runajax('picdiv', 'picnav.php?curimage=' + img);
}
Listing 7-3.The Configuration File to Manage the Gallery (config.php)
<?php
//config.php // Max dimensions of generated images
$GLOBALS['maxwidth'] = 500;
$GLOBALS['maxheight'] = 200;
// Max dimensions of generated thumbnails
$GLOBALS['maxwidththumb'] = 60;
$GLOBALS['maxheightthumb'] = 60;
// Where to store the images and thumbnails
$GLOBALS['imagesfolder'] = "images";
$GLOBALS['thumbsfolder'] = "images/thumbs";
// Allowed file types and mime types
$GLOBALS['allowedmimetypes'] = array('image/jpeg',
'image/pjpeg', 'image/png', 'image/gif');
$GLOBALS['allowedfiletypes'] = array(
'jpg' => array('load' => 'ImageCreateFromJpeg',
'save' => 'ImageJpeg'), 'jpeg' => array('load' => 'ImageCreateFromJpeg',
'save' => 'ImageJpeg'), 'gif' => array('load' => 'ImageCreateFromGif',
'save' => 'ImageGif'), 'png' => array('load' => 'ImageCreateFromPng',
'save' => 'ImagePng') );
C H A P T E R 7 ■ A R E A L - W O R L D A J A X A P P L I C AT I O N 105
Trang 9// Number of images per row in the navigation.
$GLOBALS['maxperrow'] = 7;
?>
Listing 7-4.The File Containing the PHP Functions to Be Used in the Gallery (functions.php)
<?php
// functions.php // A function to create an array of all the images in the folder function getImages()
{
$images = array();
if (is_dir($GLOBALS['imagesfolder'])) {
$files = scandir ($GLOBALS['imagesfolder']);
foreach ($files as $file) {
$path = $GLOBALS['imagesfolder'] '/' $file;
if (is_file($path)) {
$pathinfo = pathinfo($path);
if (array_key_exists($pathinfo['extension'],
$GLOBALS['allowedfiletypes']))
$images[] = $file;
} } } return $images;
} // Calculate the new dimensions based on maximum allowed dimensions function calculateDimensions($width, $height, $maxWidth, $maxHeight) {
$ret = array('w' => $width, 'h' => $height);
$ratio = $width / $height;
Trang 10if ($width > $maxWidth || $height > $maxHeight) {
$ret['w'] = $maxWidth;
$ret['h'] = $ret['w'] / $ratio;
if ($ret['h'] > $maxHeight) {
$ret['h'] = $maxHeight;
$ret['w'] = $ret['h'] * $ratio;
} } return $ret;
} // A function to change the size of an image
function createThumb($img, $maxWidth, $maxHeight, $ext = '') {
$path = $GLOBALS['imagesfolder'] '/' basename($img);
if (!file_exists($path) || !is_file($path)) return;
$pathinfo = pathinfo($path);
$extension = $pathinfo['extension'];
if (!array_key_exists($extension, $GLOBALS['allowedfiletypes'])) return;
$cursize = getImageSize($path);
$newsize = calculateDimensions($cursize[0], $cursize[1],
$maxWidth, $maxHeight);
$newfile = preg_replace('/(\.' preg_quote($extension, '/') ')$/',
$ext '\\1', $img);
$newpath = $GLOBALS['thumbsfolder'] '/' $newfile;
$loadfunc = $GLOBALS['allowedfiletypes'][$extension]['load'];
$savefunc = $GLOBALS['allowedfiletypes'][$extension]['save'];
$srcimage = $loadfunc($path);
$dstimage = ImageCreateTrueColor($newsize['w'], $newsize['h']);
C H A P T E R 7 ■ A R E A L - W O R L D A J A X A P P L I C AT I O N 107
Trang 11ImageCopyResampled($dstimage, $srcimage,
0, 0, 0, 0,
$newsize['w'], $newsize['h'],
$cursize[0], $cursize[1]);
$savefunc($dstimage, $newpath);
return $newpath;
}
?>
Listing 7-5.The PHP Code Required to Upload a File (process_upload.php)
<?php
require_once ("config.php");
require_once ("functions.php");
// Check for a valid file upload
if (!isset($_FILES['myfile']) || $_FILES['myfile']['error'] != UPLOAD_ERR_OK) exit;
// Check for a valid file type
if (in_array($_FILES['myfile']['type'], $GLOBALS['allowedmimetypes'])){ // Finally, copy the file to our destination directory
$dstPath = $GLOBALS['imagesfolder'] '/' $_FILES['myfile']['name']; move_uploaded_file($_FILES['myfile']['tmp_name'], $dstPath);
}
?>
Listing 7-6.The PHP Code to Show the Currently Selected Image (midpic.php)
<?php
//midpic.php require_once ("config.php");
require_once ("functions.php");
$imgarr = getImages();
Trang 12// If our gallery contains images, show either the selected // image, or if there are none selected, then show the first one
if (count($imgarr) > 0) {
$curimage = $_GET['curimage'];
if (!in_array($curimage, $imgarr))
$curimage = $imgarr[0];
// Create a smaller version in case of huge uploads
$thumb = createthumb($curimage,
$GLOBALS['maxwidth'],
$GLOBALS['maxheight'], '_big');
if (file_exists($thumb) && is_file($thumb)) {
?>
<div id="imagecontainer">
<img src="<?= $thumb ?>" alt="" />
</div>
<div id="imageoptions">
<a href="delpic.php?pic=<?= $curimage ?>"
onclick="removeimg ('<?= $curimage ?>'); return false">
<img src="delete.png" alt="Delete image" />
</a>
</div>
<?php
} } else echo "Gallery is empty.";
?>
Listing 7-7.The PHP Code to Show the Thumbnail-Based Navigation System (picnav.php)
<?php
//picnav.php
require_once ("config.php");
require_once ("functions.php");
C H A P T E R 7 ■ A R E A L - W O R L D A J A X A P P L I C AT I O N 109