TalkPHP

TalkPHP (http://www.talkphp.com/forums.php)
-   Absolute Beginners (http://www.talkphp.com/absolute-beginners/)
-   -   Uploading Files with PHP (http://www.talkphp.com/absolute-beginners/1231-uploading-files-php.html)

daz 09-25-2007 09:22 PM

Uploading Files with PHP
 
Uploading Files with PHP
With the release of PHP 4.1.0 came an easier and more secure method of uploading files. In this tutorial, we’ll be looking at the superglobal $_FILES, which allows us to create a basic PHP uploader in only a few lines of code. Because it is a superglobal, it is available in all scopes throughout the script.

Our first step in coding an upload script is creating the HTML form. This form will allow a user to browse for a file and then upload it to a directory. This is the code we will be using:

PHP Code:

<form action="index.php" method="post" enctype="multipart/form-data">
<
p><label for="file"><strong>File to Upload:</strong></label>
<
input type="file" name="file" id="file" /></p>
<
input type="submit" name="submit" value="Submit" /></p>
</
form

I’ll assume you have basic knowledge of HTML, so the above code should be easy to understand. Moving on to the PHP, we first need to check the form has been submitted. This is done like so:
PHP Code:

if (!isset($_POST['submit'])) {
//display the form
else {
// otherwise, process the data


Now that we know the form has been submitted, we can process the data. Luckily for us, PHP does all the work. $_FILES stores the submitted data in an array which we can access like so (“file” being the name of our form input and “name” being the file name):

PHP Code:

$_FILES["file"]["name"

Firstly, to check if there were any errors, we can use an if statement and then use die() to output an error message and stop the execution of the script.

PHP Code:

if ($_FILES["file"]["error"] > 0) {
    die(
"There was a problem uploading your file!");


Next, we need to check the type of the file. There are several ways to do this. We could use substr() to get the extension of the file or we could check the mime type of the file. We’re going to check the mime type because it’s safer and we don’t want any script kiddies uploading any malicious files. To get the mime type of a file, we use:
PHP Code:

$_FILES["file"]["type"

Then, we can make an array of allowed mime types and compare them to the uploaded file. In this tutorial, we will be checking to see if the file is an image.

PHP Code:

$types = array("image/gif""image/jpeg""image/pjpeg""image/png"); 

We can use PHP’s function in_array() to check if the file type matches any of the types in the array and then use an if statement to display an error message. We also need to make sure the file doesn’t already exist by using the file_exists() function. File_exists() checks a directory (in this case, upload/) and returns true if the file exists.

PHP Code:

if (in_array($_FILES["file"]["type"], $typestrue
    && !
file_exists("upload/" $_FILES["file"]["name"])) {
    
// continue with the script
}
else {
    die(
"File type is not allowed, or the file already exists");


Before uploading the file, we need to check the file size. This is simply done by using the following code (the size is in bytes):
PHP Code:

if($_FILES["file"]["size"] <= 120000) {
    
// continue with the script
}
else {
    die(
"File is too big!");


Now we can upload the file using move_uploaded_file(). Before the file is uploaded to the directory it is given a temporary name (“tmp_name”). Upload/ is just the directory we want to upload to.
PHP Code:

move_uploaded_file ($_FILES["file"]["tmp_name"], "upload/" $_FILES["file"]["name"]); 

Now we will put all the code together and display a message saying the file has been uploaded. Lastly, I used require() to load the HTML form.
PHP Code:

<?php
if (!isset($_POST['submit'])) {
    require(
'form.php');
}
else {

$types = array("image/gif""image/jpeg""image/pjpeg""image/png");

    if (
$_FILES["file"]["error"] > 0) {
        die(
"There was a problem uploading your file!");
    }
    else {

        if (
in_array($_FILES["file"]["type"], $typestrue
        && !
file_exists("upload/" $_FILES["file"]["name"])) {
                
            if(
$_FILES["file"]["size"] <= 120000) {
        
                if (
move_uploaded_file ($_FILES["file"]["tmp_name"], "upload/" $_FILES["file"]["name"])) {
                    echo 
"Your file was successfully uploaded!";
                }
                else {
                    die(
"The file could not be uploaded!");
                }
            }
            else {
                die(
"File is too big!");
            }
        }
        else {
            die(
"File type is not allowed, or the file already exists!");
        }
    }
}

?>

There you have it, a basic PHP file uploader. To get the script to work, you need to create a directory called upload and CHMOD it to 777. :)

Karl 09-25-2007 09:29 PM

Nice introduction to file uploads. Thanks for contributing daz :)

Wildhoney 09-25-2007 09:47 PM

Just to add onto this article. There is a function in PHP that allows you to check if the file is actually uploaded, and that it's not coming from anywhere else: is_uploaded_file(). I would also be tempted to check both the extension and the MIME type for extra security. Perhaps that's just me being somewhat cautious though.

Thanks for the article. It's very much appreciated and I'm sure it will give many people a helping hand!

jordie 09-30-2007 06:23 PM

Cool! Nice tutorial. :)

IE is kinda funny with how it gives it's mime types. For example it sends image/pjpeg where firefox or other browsers would just use image/jpeg. You've already got it in your list, but there is another one that IE uses for PNG, so you might want to expand the allowed types to:

PHP Code:

$types = array("image/gif""image/jpeg""image/pjpeg""image/png""image/x-png"); 

But I would definitely not rely solely on the mime-type. The mime-type is sent from the browser, so it is client-side generated data and therefore can be faked. Though not through a standard browser, one could infact build their own program to post a file to a site with a different mime-type. Using this method they could send a PHP file with a mime type of "image/jpeg".

Though I wouldn't stop using this method as its definitely a good test, it should in fact be built upon using the other method you and Wildhoney suggested where the actual file extension is checked. If we do this, we can ensure that no file that is uploaded has a .php/.pl/etc extension and thus can't be executed.

To do this, we'd use a white list again that is a a list of allowed extensions:

PHP Code:

$AllowedExtensions = array("png""gif""jpg""jpeg"); 

and then test using this:

PHP Code:

$FileInfo pathinfo($_FILES["file"]["name"]);
if(
in_array($FileInfo['extension'], $AllowedExtensions)){
    
// we can safely upload the file
} else {
    
// not an allowed file


Another reportedly good method if you're just uploading images, is to use the getimagesize() function. This function returns an array of the image sizes, or false if its not an image. So you could use it in this manner:

PHP Code:

if(($myImageSizes getimagesize($_FILES["file"]["tmp_name"])) !== false){
// seems like a good image! Also now have access to the width in $myImageSizes[0] and the height in $myImageSizes[1] 
} else {
// not a valid image!




All times are GMT. The time now is 03:13 AM.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0