Working with Forms in PHP, Part 2Welcome back to PHP Foundations. In my
previous column, I explained how to retrieve form data with a PHP script via the
superglobal arrays ($_GET, $_POST, and
$_REQUEST) and the import_request_variables()
function. In today's column, I'll be looking at how to accept HTTP file
uploads via PHP in a web page.
Before showing any code, it is important that I acknowledge that there are a
number of PHP configuration directives that affect the behavior of file
uploads to PHP. Specifically, the file_uploads,
uploads_max_filesize, upload_tmp_dir, and
post_max_size configuration directives have a direct bearing on
PHP's ability to accept file uploads. If you are unsure what these directives
do (or how to tell if they are set properly), please consult the PHP
manual.
The first step to a successful file upload is to ensure that your form is
constructed properly. When dealing with files in HTML, there are a couple of rules regarding the attributes the <form> tag uses. Specifically, the
enctype attribute must be set to the MIME type
multipart/form-data and the method attribute must be
set to post. As always, the action attribute should
point to the PHP script that will process the file upload. This example HTML
form uploads a file to a script named uploadproc.php:
<form method="post" action="uploadproc.php" enctype="multipart/form-data">
<input type="file" name="myfile"><br />
<input type="submit" value="Upload File">
</form>
If you haven't explored the file-uploading capabilities of HTML forms,
notice above the form element whose type attribute is set to
file. When rendered, this <input> tag will create
a text field (showing the path and file to upload) and a button (used to browse
the file system to select a file). Although not shown above, a hidden HTML form element named MAX_FILE_SIZE can be used to limit the size of the file the browser will allow the client to upload
(with the value in bytes). For instance, to limit the size of any uploaded file to no
more than one kilobyte, the following hidden element should be included:
<input type="hidden" name="MAX_FILE_SIZE" value="1024">
|
Also in PHP Foundations: |
Please note that this method of limiting the accepted file size is in no way
a fool-proof method to ensure the maximum size of uploaded files. A buggy
browser or malicious client may ignore this field entirely. If there is a real
need to limit uploaded files to a certain size, see the
upload_max_filesize PHP configuration directive in the PHP manual.
Once a form containing a uploaded file is submitted to PHP, the file will be
stored in the temporary directory specified by the upload_tmp_dir
PHP configuration directive. PHP populates the $_FILES
superglobal array with information on the uploaded file. As with the other
superglobal arrays I discussed in my previous column, $_FILES is
an associative array. It contains a key corresponding to the name attribute of
each file uploaded. When PHP receives our example form above, it will create
$_FILES['myfile'], which actually represents a sub-array populated
with information about the file that was uploaded. This information is:
name | The name of the file as it was saved on the client machine |
type | The MIME type for the file |
size | The size of the uploaded file (in bytes) |
tmp_name | The temporary name given to the file by PHP |
error | An integer error code (if something went wrong) |
Although all of the above keys will be created, they may or may not actually
contain useful values. If the client does not provide a MIME type for the
uploaded file, the type key will not have a value. Any errors that
occur during the file-uploading process are represented as one of the following
integer constants stored in the error key:
UPLOAD_ERR_OK | No error occurred. |
UPLOAD_ERR_INI_SIZE | The file was larger than PHP
will accept, based on the upload_max_filesize configuration directive. |
UPLOAD_ERR_FORM_SIZE | The file was larger than the
maximum value specified by the MAX_FILE_SIZE hidden form element. |
UPLOAD_ERR_PARTIAL | The file upload was cancelled before it was complete. |
UPLOAD_ERR_NOFILE | The form was submitted, but no file was uploaded. |
Assuming that the file was successfully uploaded, it will be stored in the
temporary directory specified by the upload_tmp_dir PHP directive
using the temporary name given in the value stored under the
tmp_name array key. PHP will automatically delete this file when
the script terminates, so you must move it if you want to keep it. To move an
uploaded file, use the move_uploaded_file() function. Although
you could use other PHP file functions, this specialized function can be more
secure. Its syntax is as follows:
move_uploaded_file($tmp_name, $newfile)
$tmp_name represents the temporary name of the uploaded file
(taken from the tmp_name array key). $newfile
represents the complete path and new filename of the uploaded file. There is no
need to specify the temporary upload directory in $tmp_name, as PHP
will automatically assume this directory. When executed, this function will
move the file and return a Boolean indicating if the file was successfully
moved or not. Below is an example script that could be used as the
uploadproc.php script in our initial HTML form for uploading a
file.
<?php
if(!isset($_FILES['myfile'])) {
die "Error! The expected file wasn't a part of the submitted form";
}
if($_FILES['myfile']['error'] != UPLOAD_ERR_OK) {
die "Error! The file uploaded failed.";
}
if(!move_uploaded_file($_FILES['myfile']['tmp_name'],
"/path/to/dir/newmyfile")) {
die "Error! Moving the uploaded file failed.";
}
echo "File successfully uploaded.";
?>
That's about all there is to uploading files from HTML forms into PHP. Of
course, the example I've discussed doesn't make use of a number of the pieces of
information provided in the $_FILES array (such as the file size,
stored in the size key), but feel free to use those values in your
scripts. This column also concludes my discussion of working with
form-submitted data in PHP. In future columns, I'll be discussing some data
validation methods--so check back soon!
John Coggeshall is a a PHP consultant and author who started losing sleep over PHP around five years ago.
Read more PHP Foundations columns.
Return to the PHP DevCenter.
Copyright © 2009 O'Reilly Media, Inc.