File uploads made easy.
Posted in Development, php on April 29, 2000
Every time I've written some code to upload a file, either to send it off as an email attachment or as an image for some dynamic content piece, I've always meant to write a few functions so I don't have to write the code again.
Well, people on the Back-end.org support board have been asking for the ability to add images to news and articles recently, so I finally sat down and wrote this script in order that I can add that functionality to the next release.
Well, people on the Back-end.org support board have been asking for the ability to add images to news and articles recently, so I finally sat down and wrote this script in order that I can add that functionality to the next release.
To make things more interesting and to make it truly re-useable, I'm going to make it totally generic so we can use it again and again for differing file types.
If you want the code to look @ in your favourite editor whilst you are reading this piece, you can download it here.
Starting us off, we need to lay down some parameters, for the maximum file size you want to allow the user to upload and - if it's an image - how high and wide the image can be, else you might get a 1.5MB, 1024 x 768 Jpeg filling up the entire screen!
$my_max_file_size = "102400"; # in bytes
$image_max_width = "300"; # in pixels
$image_max_height = "300"; # in pixels
?>
Next is the path where the resulting file will sit on your server, this should be absolute and PHP needs 'write' permissions to that directory.
$the_path = "/usr/local/apache/htdocs/sites/dev/phpbuilder/upload/files";
Now, we want to list a number of file-types so we can give sensible error messages later on in the script. This is simply an array indexed by 'content-types' with a value that is human readable
$registered_types = array(
"application/x-gzip-compressed" => ".tar.gz, .tgz",
"application/x-zip-compressed" => ".zip",
"application/x-tar" => ".tar",
"text/plain" => ".html, .php, .txt, .inc (etc)",
"image/bmp" => ".bmp, .ico",
"image/gif" => ".gif",
"image/pjpeg" => ".jpg, .jpeg",
"image/jpeg" => ".jpg, .jpeg",
"application/x-shockwave-flash" => ".swf",
"application/msword" => ".doc",
"application/vnd.ms-excel" => ".xls",
"application/octet-stream" => ".exe, .fla (etc)"
); # these are only a few examples, you can add as many as you like
Finally, we want to specify what type of file the user is allowed to upload, for this example, it's an image that we might want to embed in a web page, so we build up an array of related 'image' content-types.
$allowed_types = array("image/bmp","image/gif","image/pjpeg","image/jpeg");
An OO developer would probably make this whole script a class and have each one of the following functions as methods. Personally, I prefer to write my code using a function based approach.
To start us off, I want to write the upload form as a small function, I can then call it many times in this code without lots of messy repeating. If you are wondering why there are lots of n's everywhere, this is so that the outputted HTML is not all squashed onto one line. In bigger applications it makes for easier debugging when you view source, so I'm not being anal for no reason.
function form($error=false) {
global $PHP_SELF, $my_max_file_size;
if ($error) print $error . "
";
print "\n";
print "\n";
print "\n";
print "\n
Upload a file";
print "\n
NOTE: Max file size is " . ($my_max_file_size / 1024) . "KB";
print "\n
";
print "\n";
print "\n";
}
Note, the if we don't add this nothing will get uploaded. I've also set the parameter $error to false, this is a nice way of pre-defining the value, so I don't have to always pass the parameter in.
Our second function is to check if a certain value is in an array, now PHP4 has this built in, but PHP3 does not, so we wrap an IF statement around it checking the PHP version, if you are running PHP4, you can delete the whole thing but I've left in so it can use it on differing servers without too much thought.