Simple Debugging in PEAR::DB
Back-End Full-Stack Web Leveling UpOne of the most important (and least loved) activities in a programmer's life is debugging code. When debugging PHP, there are several strategies, ranging...
5 min read
Dec 18, 2005
Content management is a nearly universal challenge when discussing any data-driven web site. As a developer, you can create your own system or use any one of a number of sophisticated open-source or third-party packages. Many times, however, you have a simple concept in mind and you want to create your own – especially if you have very specific needs that existing solutions cannot easily accommodate. At some point, you are going to want to let users upload files. Sometimes reluctantly, but it will happen. PHP 5 handles this need very well.
In this article, we look at a simple strategy for allowing users to upload images to your web site.
We are going to look at an example where we want to allow someone to upload images to a web site (for a soon-to-be famous website www.lookatmyawesomevacation.com). We are going to place some restrictions on file size, and permit only certain kinds of images. Making the web interface elegant and appropriate is left to the reader as homework.
There are several components necessary for file uploads to work properly:
(HTML) use a multipart form
(HTML) create the upload control and size field
(PHP) check for errors
(PHP) ensure validity of upload
(PHP) upload file to web server
Our first step is to create a nice web page with the appropriate HTML for the file upload to work. We will call this page file_upload.html (and show what it looks like in Safari)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Upload Your Images</title>
</head>
<body>
<form method='POST' name='my_form' enctype='multipart/form-data' action='do_upload.php'>
<input type='hidden' name='MAX_FILE_SIZE' value="262144" />
Which image? <input name="upload_file" type="file" />
<br /><br />
<input type="submit" value="Send Selected Image" />
</form>
</body>
</html>
Let’s take a closer look at that code. First and foremost, your form must have enctype=’multipart/form-data’ among its attributes. In addition, this is one place you can specify a file size restriction. If you do so, the name of the field must be MAX_FILE_SIZE and its value is the number of bytes (in our case, 256K, which is 262144 bytes).
Your HTML form is not the only place where file size can be restricted. The server’s php.ini file also has a section related to file uploads. If you open php.ini in your favorite editor, and skip far enough down the file, you will see:
;;;;;;;;;;;;;;;;
; File Uploads ;
;;;;;;;;;;;;;;;;
; Whether to allow HTTP file uploads.
file_uploads = On
; Temporary directory for HTTP uploaded files (will use system default if not
; specified).
;upload_tmp_dir =
; Maximum allowed size for uploaded files.
upload_max_filesize = 2M
As you can see, php.ini also controls whether file uploads will be allowed at all. The file size specified here is entered in megabytes (e.g., 2M represents 2 megabytes). Both the form-based limit and php-based limit generate different error messages when you act on the uploaded file.
If you aren’t sure where php.ini is located on your server, create a tiny script with this simple code:
<?php
phpinfo();
?>
When you run that script in your browser, the first block on the resulting page will have an item called “Configuration File (php.ini) Path” that will tell you where the php.ini file is located. Obviously, if you are using PHP as part of a hosting package, you may not have any control over this file at all.
Now that we have our HTML form, we need our PHP script to handle its results. We will call this script do_upload.php (whatever name we choose must match the action attribute of the <form> in our HTML page).
<?php
$err_upload = "";
$image_file = <b>$_FILES['upload_file']</b>;
$temporary_name = $image_file['tmp_name'];
if (<b>is_uploaded_file($temporary_name)</b>) {
// get image information
$image_metadata = <b>getimagesize($temporary_name)</b>;
if ($image_metadata) {
$image_width = $image_metadata[0];
$image_height = $image_metadata[1];
$image_type = <b>$image_metadata[2]</b>;
$save_name = $temporary_name;
switch ($image_type)
{
case IMAGETYPE_GIF:
$save_name .= ".gif";
break;
case IMAGETYPE_PNG:
$save_name .= ".png";
break;
default:
$err_upload = "Sorry... we only allow gif and png images.";
break;
}
if (! $err_upload) {
if (<b>move_uploaded_file($tmp_name, "/path/to/images/$save_name")</b>) {
// you might update a database with key information here so
// that the image can be used later
} else {
$err_upload = "Sorry... something went horribly awry.";
}
}
}
} else {
// some error occurred: handle it
switch ($image_file['error'])
{
case 1: // file too big (based on php.ini)
case 2: // file too big (based on MAX_FILE_SIZE)
$err_upload = "Sorry... image too big.";
break;
case 3: // file only partially uploaded
case 4: // no file was uploaded
case 6: // missing a temporary folder
case 7: // failed to write to disk (only in PHP 5.1+)
$err_upload = "Sorry... failed to upload... problem with server.";
break;
}
}
if ($err_upload) {
print $err_upload;
} else {
print "Success!!!";
}
?>
Okay, there is a lot going on here, but there are really only a few key steps in the process.
We use the $_FILES superglobal array to get our file content (‘upload_file’ is the name of the file field in our HTML form).
We use “if (is_uploaded_file($temporary_name))” as the safest way to test whether the upload worked or not.
Since our example is considering only images, we can use “if ($image_metadata)” because it identifies the image as either an image or not (it recognizes many different types).
We use “move_uploaded_file($tmp_name, “/path/to/images/$save_name”)” to put the uploaded file in our desired destination. One common mistake is when the desired directory does not have the correct file permissions so that PHP can work its magic.
Everything else in that script handles various error conditions: from fundamental problems with the upload process to non-image data being uploaded to non-gif and non-png images being uploaded. PHP gives you a tremendous amount of control over the process.
This is only an introductory look at file uploads. There are many other considerations when doing this kind of work. For example, instead of uploading the file to the server, it may be desirable to have the file made part of the database that feeds your web site. Or, you may want images but may want to create thumbnails of those images and save them into the database while referencing the larger files. The possibilities are endless.
One of the most important (and least loved) activities in a programmer's life is debugging code. When debugging PHP, there are several strategies, ranging...
Now that PHP 5 is becoming more and more prevalent over its predecessors, some really good books that cover PHP need revisions. Nowhere is...