advanced php file uploads

27
Advanced PHP File & Image Uploads

Upload: valatopia

Post on 13-Nov-2014

358 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Advanced Php File Uploads

Advanced PHP

File & Image Uploads

Page 2: Advanced Php File Uploads

Uploads In some dynamic web applications, it is

necessary to allow users to upload files from their local computer to the Web server.

Such an application may allow users to share files with others or simply provide a mechanism for storing files for later use.

Page 3: Advanced Php File Uploads

PHP File Functions move_uploaded_file(filename, destination)

moves a file to a specified destination on the server.

is_uploaded_file ( string $filename ) Returns TRUE if the file named by filename was

uploaded via HTTP POST. This is useful to help ensure that a malicious user hasn't tried to trick the script into working on files upon which it should not be working--for instance, /etc/passwd.

Page 4: Advanced Php File Uploads

PHP File Functions cont. copy ( string $source , string $dest [, resource

$context ] ) Makes a copy of the file source to dest .

rename ( string $oldname , string $newname [, resource $context ] ) Renames a file or directory

unlink ( string $filename [, resource $context ] ) Deletes a file

Page 5: Advanced Php File Uploads

The Form Before we look at the details of the PHP code,

lets focus on the XHTML form controls needed to create the file upload page.

<form enctype="multipart/form-data" action="upload.php" method="post">

Select File: <input type="file" name="uploadFile">

<input name="Submit" type="submit" value="Upload File">

</form>

A form used for file uploads must include the encode type or "enctype" attribute.

The value of the enctype attribute "multipart/form-data" should be included when a form is used to upload files.

Page 6: Advanced Php File Uploads

The Form cont. Following the <form> is an <input> text box control. This control is used to specify the location and name

of the file that will be uploaded. The control includes a name and type attribute. The type attribute must be set to "file". The name is a user-defined value that will be used by

the server to identify the source file during the upload process.

The file text box also includes a "Browse..." button when viewed in the browser window. When the browse button is clicked, a dialog window appears and allows the user to browse their local computer for the file that will be uploaded.

Page 7: Advanced Php File Uploads

Generic PHP Upload Script<?php

if ($_POST[‘Submit’] == "Upload File") { move_uploaded_file ($_FILES['uploadFile'] ['tmp_name'],

"uploads/{$_FILES['uploadFile'] ['name']}");echo "File uploaded.";

} ?>

<form enctype="multipart/form-data" action="upload.php" method="post">

Select File: <input type="file" name="uploadFile">

<input name="Submit" type="submit" value="Upload File">

</form>

Page 8: Advanced Php File Uploads

Whats Happenin? When the "Upload File" button is clicked, the

file specified in the <input type="file" name="UploadFile"/> is automatically posted to a temporary folder on the webserver

When the "Upload File" button is clicked, the file specified in the <input type="file" name="UploadFile"/> is automatically posted to a temporary folder on the webserver..

Page 9: Advanced Php File Uploads

What’s goin on – move_uploaded_file()? The first parameter of the function -

$_FILES['uploadFile'] ['tmp_name'], becomes a reference to the file as the function prepares to move it to its final destination.

The second parameter - “/uploads/FILES['uploadFile'] ['name']}", is a relative path to the folder were the file will be permanently saved.

The last part of the path includes the code - {$_FILES['uploadFile'] ['name']}. This can be interpreted as the name of the file which was entered into the file text box named "uploadFile".

Page 10: Advanced Php File Uploads

move_uploaded_file cont. In short, the move_uploaded_file() function

moves the file from a temporary upload folder to the folder ($_FILES['uploadFile'] ['tmp_name']) to the folder (“/uploads”) and the file is saved with the same name as entered by the user ({$_FILES['uploadFile'] ['name']}).

Files can be uploaded to any directory on the web server, however, the destination folder must have "write" access permissions.

Page 11: Advanced Php File Uploads

Setting Permissions On our local machines,

set up permissions by right clicking on the folder and choosing properties.

Then click the ‘Allow’ button to allow full control of the folder.

On a web server, set the permissions to 777.

Page 12: Advanced Php File Uploads

Uh-Oh! We have not considered what happens when

a user attempts to upload a file that exceeds size limits, if the upload folder does not have appropriate security permissions, or some unforeseen network issue prevents the entire file from being uploaded.

To improve the file upload code, we must provide routines that check for errors and provide feedback to the user on how to correct these problems.

Page 13: Advanced Php File Uploads

Adding Error Checkingif ($_POST['Submit'] == "Upload File"){

move_uploaded_file ($_FILES['uploadFile'] ['tmp_name'], "uploads/{$_FILES['uploadFile'] ['name']}");

if($_FILES['uploadFile'] ['error'] > 0) { switch ($_FILES['uploadFile'] ['error']){

case 1: echo 'File exceeded maximum server upload size'; break; case 2: echo 'File exceeded maximum file size'; break; case 3: echo 'File only partially uploaded'; break; case 4: echo 'No file uploaded'; break;

} } else{ echo 'File successfully uploaded'; } }

Page 14: Advanced Php File Uploads

The Form for Error Checking

Another new feature included in this example is an XHTML hidden text box called "MAX_FILE_SIZE". This is a special hidden tag that can be used with the file tag <input type="file" name="uploadFile"/> to set a maximum file size..but it cannot be relied upon.

Use the php.ini setting as well.

<form enctype="multipart/form-data" action="upload.php" method="post">

Select File: <input type="file" name="uploadFile"> <input type="hidden" name="MAX_FILE_SIZE" value="1000000"/> <input name="Submit" type="submit" value="Upload File">

</form>

Page 15: Advanced Php File Uploads

What else? We know that we want to allow someone to

upload files – but the question is, what kind of files?

Should we allow to upload .dll, exe, .php files? What if they are uploading code that will execute and destroy our database?

We should limit the uploads to .pdf, .doc, .jpg, .gif, etc.

Page 16: Advanced Php File Uploads

Finding the file type We can use: $_FILES["uploadFile"]["type"] to

find the name of the file before excepting it: $_FILES is the name to use for any file upload The second part [“uploadFile”] is the name of

the file input field The third, [“type”] is the mime type of the file

uploaded Getting this ‘type’ will allow us to create if

statements that will check to see if it is an allowed file – and it will also allow us to apply different file handling.

Page 17: Advanced Php File Uploads

Acceptable File Types For our purposes,

we only want to allow the following File Types: jpeg,png word,pdf,avi videos

Use PHP to check the file type:

if($_FILES['uploadFile'] ['error'] > 0) {switch ($_FILES['uploadFile'] ['error']){case 1: echo 'File exceeded maximum server upload

size';break;case 2: echo 'File exceeded maximum file size';break;case 3: echo 'File only partially uploaded';break;case 4: echo 'No file uploaded';break;}

}$aryImages=array(“image/jpeg","image/png");$aryDocs=array("application/msword","application/pdf","video/x-msvideo");if (in_array($_FILES["uploadFile"]["type"],$aryImages)){

//do image stuff}elseif (in_array($_FILES["uploadFile"]["type"],$aryDocs)){

//do doc stuff}

Page 18: Advanced Php File Uploads

GD To create images with PHP you need to have

the gd image library installed and activated in your PHP.

To see if it is installed, view your phpinfo file. If GD is enabled, you will see the following:

Page 19: Advanced Php File Uploads

Thumbnails We want to create a thumbnail version of any

image that is uploaded. We assume the thumbnail should be 100 pixels, either

wide or high. We load the original image, and check its dimensions. If the picture is higher than wide, we set the height of the

thumb to 100 pixels. The width of the thumbnail is the original width multiplied

with 100 pixels divided by its height. Thumbnail height = original width * (100 / original height,

preserving the original aspect ratio. If the original picture is wider than high, we do the same

to the height of the thumbnail. If they are the same, we simply create a 100x100 pixels

image.

Page 20: Advanced Php File Uploads

GD cont. If you know for sure that there is gd on the

machine but PHP does not recognize it, it may still be commented in the php.ini.

Scan your machine for the php.ini and edit it. You will find loads of extensions, simply remove the semicolon in front of the gd dll and restart the server:

Page 21: Advanced Php File Uploads

PHP GD Functions PHP has a whole lot of functions to help us

with generating graphics with gd. The ones we need to use here are:

imageCreateFromJPEG() to create a copy to work on of a .jpg image.

imageCreateFromPNG() to create a copy to work on of a .png image.

imageSX() to get the width of the original image. imageSY() to get the height of the original image. imageCreateTrueColor() to create a new true color

image object. imageCopyResampled() to resample the image.

Page 22: Advanced Php File Uploads

Never assume the user won’t make mistakes! Always plan for the worst What will happen if the user uploads a file

with the same name as a file that was already uploaded?

Will it overwrite the original file? What about the filename? What if it has

invalid characters? (%& #, etc.)

Page 23: Advanced Php File Uploads

Checking the File Name This function is going to

check the filename for invalid characters, spaces, etc. It is also going to check the database to see if any files have been inserted with that name already – if so, we break it apart, insert the unique timestamp into the filename and put it back together again.

function filenameSafe($filename) {$temp = $filename;// Lower case$temp = strtolower($temp);// Replace spaces with a ’_’$temp = str_replace(" ", "_", $temp);// Loop through string$result = "";for ($i=0; $i<strlen($temp); $i++) {

if (preg_match('([0-9]|[a-z]|_|.)', $temp[$i])) {$result = $result.$temp[$i];

}}dbConnect();$SQL="SELECT fileID FROM tblFile WHERE fileName='".

$result."'";$rs=mysql_query($SQL);if (mysql_num_rows($rs)!=0){

$extension=strrchr($result,'.');$result=str_replace($extension,time(),$result);$result=$result.$extension;

}return $result;

}

Page 24: Advanced Php File Uploads

Calling the function Notice our function takes one parameter only,

the file name – this makes invoking this function pretty easy:

A safe, clean, unique filename is returned

$filenameSafe=filenameSafe($_FILES['uploadFile'] ['name']);

Page 25: Advanced Php File Uploads

function createThumb($type,$tmpname,$filename,$new_w,$new_h){$thumbFilename="tmb-".$filename;if (is_numeric(strpos($type,"jpeg"))){

$src_img=imagecreatefromjpeg($tmpname);}if (is_numeric(strpos($type,"png"))){

$src_img=imagecreatefrompng($tmpname);}$old_x=imageSX($src_img);$old_y=imageSY($src_img);if ($old_x > $old_y) {

$thumb_w=$new_w;$thumb_h=$old_y*($new_h/$old_x);

}if ($old_x < $old_y) {

$thumb_w=$old_x*($new_w/$old_y);$thumb_h=$new_h;

}if ($old_x == $old_y) {

$thumb_w=$new_w;$thumb_h=$new_h;

}$dst_img=imagecreatetruecolor($thumb_w,$thumb_h);imagecopyresampled($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y);if (is_numeric(strpos($type,"jpeg"))){

imagejpeg($dst_img,"../uploads/".$thumbFilename);imagejpeg($src_img,"../uploads/".$filename);

}if (is_numeric(strpos($type,"png"))){

imagepng($dst_img,"../uploads/".$thumbFilename);imagepng($src_img,"../uploads/".$filename);

}imagedestroy($dst_img);imagedestroy($src_img);dbInsert($filename,$thumbFilename,$type);

}

Page 26: Advanced Php File Uploads

Adding to the database Our function to add to the database is simple:

Calling it is easy too – if it’s an image we have the thumbnail filename renamed with ‘tmb-’ at the beginning –

Otherwise (a document) we send a blank value:

function dbInsert($filename,$thumbFilename,$type){dbConnect();$SQL="INSERT Into tblFile (fileName,thumbFileName,fileType) values('".$filename."','".$thumbFilename."','".

$type."')";echo $SQL;mysql_query($SQL);

}

dbInsert($filename,$thumbFilename,$type);

move_uploaded_file ($_FILES['uploadFile'] ['tmp_name'], "../uploads/".$filenameSafe);dbInsert($filenameSafe,'',$fileType);

Page 27: Advanced Php File Uploads

Wrapping up It may take some fine tuning – but this will

leave you with a working script to upload images and documents.

Note: GD does NOT work with .gif files because the technology that makes .gif files is copyrighted.

Another great piece of software to manipulate images is ImageMagick.