Feb 27 2008
Uploading Files
Uploading file is one of the most convenient things to do with PHP. This tutorial will cover how to upload files safely and how to ensure no files are replaced in the process.
The first step would be creating your form, this will be a basic HTML form with the attribute encrypt added to it, this tells PHP we are trying to upload a file, you will not be able to upload a file without it. I have also added a button to the forum, this will be the event handling button, we will check to see if this button has been posted before we try and upload a file.
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="uploaded_file">
<input type="submit" name="sendForm" value=" upload image">
</form>
Next we check to see if the button has been submitted, we identify this by checking for the posted super global named sendForm as this is the name of the button on our form.
if (!empty($_REQUEST['sendForm']))
{
// Upload the files process will go here.
}
When a file type is attached to a form and the form is posted the file is uploaded to a tempory directory called /tmp usually, once the file has uploaded you need to move the file from the temp directory into your preferred directory.
We can access the files array by using the files array super global.
The following is posted in the $_FILES array.
[tmp_name] the location of the temporary file and the name of the file
[name] the original file name
[errors] error number, this will be zero if everything is ok
[size] the size of the file.
This is how we access the files array, it is a multi-dimensional array so we need the name of the posted file and then the attribute in each call to the super global.
if (!empty($_REQUEST['sendForm']))
{
$name = $_FILES['uploaded_file']['name']; // Assign the name to a variable
$tmp_name = $_FILES['uploaded_file']['tmp_name']; // Assign the tmp_name to a variable
$error = $_FILES['uploaded_file']['error']; // Assign the error to a variable
$size = $_FILES['uploaded_file']['size']; // Assign the size to a variable
}
You should also declare the directory where you want to save the file, make sure the directory permissions allows you to upload to this folder, this can be done by using a client like <a href="http://www.pspad.com">PsPad</a> or <a href="filezilla.sourceforge.net/">FileZilla</a> by clicking the folder and changing the permissions (CHMOD).
$uploadFilesTo = 'my_folder/my_file'; // No trailing slash
Now we have assigned the names of all the files array then can be called directly from the variables.
Now because we have no control over the name of the file i suggest we rename the file by removing any non-standard characters, this can be done like so.
$name = ereg_replace('[^A-Za-z0-9.]', '-', $name);
This will basically remove anything apart from characters, numbers and the full stop for the file extension.
Now we have a safe filename let's see see if it's one of the file types we don't allow people to upload, so we are going to create a comparison array for this.
$naughtyFileExtension = array("php", "php3", "asp", "inc", "psd");
Now we have the array we need to compare the file extension against the array, like so. This also requires us to get the file extension using the <a href="http://uk3.php.net/pathinfo/">pathinfo</a> function.
$fileInfo = pathinfo($name); // Returns an array that includes the extension
if (!in_array($fileInfo['extension'], $naughtyFileExtension))
{
// The file is ok, we can upload it.
}
else
{
// The file uses an extension we don't want to upload
}
Now, if we have gotten this far and we want to upload the file then the next step is to ensure that the file doesn't already exist on the server because by default it will replace the old file, this can be done using the function <a href="http://uk3.php.net/file_exists">file_exists, but i am also going to use a recursive function to continuously keep checking until it doesn't exist</a>.
$name = getNonExistingFilename($uploadFilesTo, $name);
function getNonExistingFilename($uploadFilesTo, $name)
{
if (!file_exists($uploadFilesTo.'/'.$name))
return $name;return getNonExistingFilename($uploadFilesTo, rand(100, 200).'_'.$name);
}
This will add a prefix onto the image and will ensure it won't be replaced. If you prefer you could add a suffix before the extension.
Now if we can clarify the file doesn't exist then we can upload the file like so.
if (move_uploaded_file ($tmp_name, $name))
{
echo '<p>File uploaded</p>';
}
else
{
echo '<p>File failed to upload</p>';
}
So that's it, this is pretty durable code, have fun with it.
<?php
error_reporting(E_ALL ^ E_NOTICE); // Show all major errors.
// Check to see if the button has been pressed
if (!empty($_REQUEST['sendForm']))
{
// Assign the name to a variable
$name = $_FILES['uploaded_file']['name'];
// Assign the tmp_name to a variable
$tmp_name = $_FILES['uploaded_file']['tmp_name'];
// Assign the error to a variable
$error = $_FILES['uploaded_file']['error'];
// Assign the size to a variable
$size = $_FILES['uploaded_file']['size'];
// No trailing slash
$uploadFilesTo = 'up';
// Create safe filename
$name = ereg_replace('[^A-Za-z0-9.]', '-', $name);
// Disallowed file extensions
$naughtyFileExtension = array("php", "php3", "asp", "inc", "psd");
// Returns an array that includes the extension
$fileInfo = pathinfo($name);
// Check extension
if (!in_array($fileInfo['extension'], $naughtyFileExtension))
{
// Get filename
$name = getNonExistingFilename($uploadFilesTo, $name);
// Upload the file
if (move_uploaded_file($tmp_name, $uploadFilesTo.'/'.$name))
{
// Show success message
echo '<p>File uploaded to '.$uploadFilesTo.'/'.$name.'</p>';
}
else
{
// Show failure message
echo '<p>File failed to upload to '.$uploadFilesTo.'/'.$name.'</p>';
}
}
else
{
// Bad File type
echo '<p>The file uses an extension we don't want to upload</p>';
}
}// Functions do not need to be inline with the rest of the code
function getNonExistingFilename($uploadFilesTo, $name)
{
if (!file_exists($uploadFilesTo . '/' . $name))
return $name;return getNonExistingFilename($uploadFilesTo, rand(100, 200) . '_' . $name);
}
?><form action="" method="post" enctype="multipart/form-data">
<input type="file" name="uploaded_file">
<input type="submit" name="sendForm" value=" upload image ">
</form>
Good luck.
