PHP Developers Network

A community of PHP developers offering assistance, advice, discussion, and friendship.
 
Loading
It is currently Wed Jul 08, 2020 12:00 am

All times are UTC - 5 hours




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: File Upload Class
PostPosted: Sun Jan 25, 2004 10:27 am 
Offline
DevNet Resident

Joined: Sun Jul 20, 2003 9:25 pm
Posts: 1150
Location: West Yorkshire, England
Heres a nice file upload class i wrote that will handle all your uploading needs :) (or at least i hope so). It has its own basic form - but you can write your own and it will still work with the class.

It uploads most file types and you can add which types you want to a data array in the class. If your uploading images it can also resize them automatically if they are too big for what you want (controled by your max width/height info). It then also makes thumbnails for you if you want. The GD library is of course needed for this - but it comes with the newest php installations, so i hope thats not a problem for people.

Ive tested it a fair bit, and cant find any errors - but please tell me if you find any. Anyway, this class should help most people out and make uploading files easy as pie :)

As usual, please give me your feedback.

Syntax: [ Download ] [ Hide ]
<?php

###################################################################################################

##                                    File Upload Class - v1.0                                   ##

##                                     http://www.akvoid.com                                     ##

##                                Written By startx - Jacob Wyke                                 ##

##                                     startx@aknetwork.org                                      ##

###################################################################################################

##

##      This class handles all your file uploading needs. It can handle most file types - you can add

##  more if needed (just add them to the array in the file_types() function. To use this class

##  for yourself do the following:

##

##  USAGE:

##-------------------------------------------------------------------------------------------------

##

##     include('this_file_name.php');

##     $upload_class = new File_Upload('upload directory',

##                                     'max_file_size',

##                                     'file__types_array',

##                                     'upload_field_name',

##                                     'upload_fix_prefix'

##                                    );

##

##    if(!$_POST[submit]){

##       #shows the default upload form included with the class - you can make your own

##       echo $upload_class->default_form('file_upload.php');

##    }else{

##       $image[width] = '300';                 #max image width

##       $image[height] = '250';                #max image height

##       $image[thumbs] = '0';                  #make thumbnail of image

##       $image[thumb_width] = '100';   #thumbnail width

##       $image[thumb_height] = '70';   #thumbnail height

##       $image[resize] = '1';                  #should images be automatically resized

##       $image[skip_resize] = '0';     #skip image resizing - shows no "image too big" error

##

##       #processes the submitted form and returns any error or success message

##       echo $upload_class->process($image);

##

##       #array containing the location of all uploaded files so you can add them to a database/file etc

##       $uploaded_files = $upload_class->output;

##    }

##

##

##-------------------------------------------------------------------------------------------------

##

##  The example above shows you how to control the class if you wish to only upload images,

##  if you want to just upload files to the server then do the same except exclude all the

##  $image array vars and DO NOT pass it to the "echo $upload_class->process($image);" line

##

##  e.g.

##              echo $upload_class->process();

##

##

##  Further explainations for calling the class

##

##              'upload directory'      - The directory where you want to store the uploaded files

##                                                        Make sure you make it writable by the server.

##

##              'max_file_size',        - This is the maximum allowed file size to be uploaded in bytes.

##                                                        Default is set to 51200 which is 500kb

##

##              'file_types_array'      - This is an array containing your own file types. By default

##                                                        the script allows all the file types shown in the file_types() function

##                                                        but if you pass your own array of them - then only those types are

##                                                        allowed. This allows you to limit the types of files. You could of

##                                                        course just delete any unwanted types from the array in file_types()

##

##              'upload_field_name' - This is the name of the file field in the form - only use if you

##                                                        make your own form and dont use the one included in this class.

##

##              'upload_fix_prefix' - Allows you to add a prefix to all files you upload so that you

##                                                        can better organise them.

##

##  All of these are optional and so you can just call the class with 'new File_Upload();'

##

###################################################################################################

##

##  LICENSE

##

##  Please feel free to use/edit this class as you wish but for non-commercial uses ONLY. If

##  you wish to use it for a commercial product that will be sold then please contact me

##  further for usage details. You must also keep this license and my contact details attached

##  somewhere to this class file.

##

##  Other than that please feel free to use and play with it and give me feedback and info

##  on what your using it for

##

##  Enjoy!

##

##  Jacob Wyke - startx@aknetwork.org

##

###################################################################################################



class File_Upload{



   var $allow_types;

   var $field_name;

   var $dir;

   var $file_prefix;

   var $file_max_size;

   var $location;

   var $thumb_location;

   var $output;



   ##--------------------------------------------

   ##CLASS CONSTRUCTOR

   ##--------------------------------------------

   function File_Upload($dir = 'uploads', $size = '512000', $types = '0', $name = 'upload', $pre = ''){

      #creates array of allowed file types if you dont enter your own

      if($types == '0'){

         $this->file_types();

      }else{

         $this->file_types = $types;

      }



      $this->field_name = $name;        #name of the upload field in form

      $this->dir = $dir;                        #name of upload directory

      $this->file_prefix = $pre;        #file prefix

      $this->file_max_size = $size; #max file size

      $this->output = array ();         #makes array to store loction of uploaded files so you know what was uploaded

   }



   ##--------------------------------------------

   ##FILE TYPES FUNCTION

   ##Fills the array with the types of files you want to allow

   ##You can add your own list of file types to the array below

   ##--------------------------------------------

   function file_types(){

      $this->allow_types = array (

         'text/html',

         'text/plain',

         'text/css',

         'image/gif',

         'image/x-png',

         'image/jpeg',

         'image/tiff',

         'image/x-ms-bmp',

         'audio/x-wav',

         'application/x-pn-realaudio',

         'video/mpeg',

         'video/quicktime',

         'video/x-msvideo',

         'application/postscript',

         'application/rtf',

         'application/pdf',

         'application/x-pdf',

         'application/x-gtar',

         'application/x-tar',

         'application/zip',

         'application/x-zip-compressed',

         'application/mac-binhex40',

         'application/x-stuffit',

         'application/octet-stream',

         'text/javascript',

         'application/x-javascript',

         'application/x-sh',

         'application/x-csh',

         'application/x-perl',

         'application/x-tcl',

         'application/vnd.ms-powerpoint',

         'application/ms-powerpoint',

         'application/vnd.ms-excel',

         'application/msword',

         'video/avi',

         'java/*',

         'application/java',

         'image/x-icon',

         'image/bmp',

         'image/pjpeg',

         'application/x-bittorrent'

      );

   }



   ##--------------------------------------------

   ##PROCESS FUNCTION

   ##Processes the file upload

   ##--------------------------------------------

   function process($image = '0'){

      #checks that file was uploaded

      if(!file_exists($_FILES[$this->field_name][tmp_name])){

         return $this->error(1);

      }else{

         #checks that the file isnt too large

         if($_FILES[$this->field_name][size]>$this->file_max_size){

            return $this->error(2);

         }else{

            #checks to see if file type is allowed

            if(!in_array($_FILES[$this->field_name][type],$this->allow_types)){

               return $this->error(3);

            }else{

               #Repeat loop till you find an available file name

               $loop = '0';

               do{

                  $loop++;

                  #create new file location

                              $this->location = $this->dir."/".$loop."_".$this->file_prefix.$_FILES[$this->field_name][name];

                              $this->thumb_location = $this->dir."/thumb_".$loop."_".$this->file_prefix.$_FILES[$this->field_name][name];

               }while(file_exists($this->location));



               #processes file for image stuff

               if($image){

                  $outcome = $this->process_image($image);

                  if(!$image[skip_resize]){ #dont need to rename the orignal as we have skipped the resizing

                     $this->location = $this->dir."/orig_".$loop."_".$this->file_prefix.$_FILES[$this->field_name][name];

                  }

               }



               if($outcome){

                  #returns any errors from the image function

                  return $outcome;

               }else{

                  #moves the original file from the tmp dir to where you want to store them

                  if(!copy($_FILES[$this->field_name][tmp_name], $this->location)){

                     return $this->error(4);

                  }else{

                     array_push($this->output, $this->location);

                     #The upload was successful - the locations of all files uploaded are stored in $this->ouput.

                     return "The file was successfully uploaded.";

                  }

               }

            }

         }

      }

   }



   ##--------------------------------------------

   ##PROCESS IMAGE FUNCTION

   ##Processes images

   ##--------------------------------------------

   function process_image($image){

      #gets the image dimensions

      $size = getimagesize($_FILES[$this->field_name][tmp_name]);

      #makes sure the image isnt larger than your max width/height

      if((($size[0]>$image[width]) OR ($size[1]>$image[height])) AND !$image[resize] AND !$image[skip_resize]){

         return $this->error(5);

      }else if(($size[0]>$image[width]) OR ($size[1]>$image[height]) AND $image[resize]){

         #resize the image if wanted

         if(!$image[skip_resize]){

            $height=(int)(($image[width]*$size[1])/$size[0]);

            $this->make_image($this->location, $image, $size, $image[width], $height);

         }

      }



      #make thumbnail of image if needed

      if($image[thumbs]){

         $this->make_image($this->thumb_location, $image, $size, $image[thumb_width], $image[thumb_height]);

      }

   }



   ##--------------------------------------------

   ##MAKE IMAGE FUNCTION

   ##Makes image

   ##--------------------------------------------

   function make_image($location, $image, $size, $width, $height){

      if($_FILES[$this->field_name][type]=='image/gif'){

         if(function_exists('imagecreatefromgif')){

            $im = @imagecreatefromgif($_FILES[$this->field_name][tmp_name]);

         }else{

            echo $this->error(6);

            exit;

         }

      }

      if($_FILES[$this->field_name][type]=='image/jpeg' OR $_FILES[$this->field_name][type]=='image/pjpeg'){

         if(function_exists('imagecreatefromjpeg')){

            $im = @imagecreatefromjpeg($_FILES[$this->field_name][tmp_name]);

         }else{

            echo $this->error(6);

            exit;

         }

      }

      if($_FILES[$this->field_name][type]=='image/x-png'){

         if(function_exists('imagecreatefrompng')){

            $im = @imagecreatefrompng($_FILES[$this->field_name][tmp_name]);

         }else{

            echo $this->error(6);

            exit;

         }

      }



      if(!$im){

            echo $this->error(7);

            exit;

      }else{

         $dst_img = imagecreatetruecolor($width,$height);

         imagecopyresized($dst_img, $im, 0, 0, 0, 0, $width, $height, $size[0], $size[1]);

         imagejpeg($dst_img, $location, 75);

         array_push($this->output, $location);

      }

   }



   ##--------------------------------------------

   ##ERROR FUNCTION

   ##Returns error messages

   ##--------------------------------------------

   function error($num){

      switch($num){

         case '1':

            $err = "There was an error uploading the file to the server.";

            break;

         case '2':

            $err = "The uploaded file was too large - max size is ".round($this->file_max_size/1024)."kb";

            break;

         case '3':

            $err = "This server does not accept the file type you attempted to upload.";

            break;

         case '4':

            $err = "The uploaded file could not be moved from its temporary location.";

            break;

         case '5':

            $err = "The image dimensions were too big.";

            break;

         case '6':

            $err = "This type of image cannot be manipulated.";

            break;

         case '7':

            $err = "An error occured when resizing the image.";

            break;

      }

      return $err;

   }



   ##--------------------------------------------

   ##DEFAULT FORM FUNCTION

   ##Shows a very basic form for the upload

   ##--------------------------------------------

   function default_form($action, $class = '', $button_class = ''){

      $text = "

         <form method="
POST" action="$action" name="file_upload" enctype="multipart/form-data">

            File: <input class="
$class" type="file" name="upload" size="25">

            <br />

            <input class="
$button_class" type="submit" name="submit" value="Upload">

         </form>

      "
;

      return $text;

   }



}



?>


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 25, 2004 5:23 pm 
Offline
DevNet Master

Joined: Thu Jan 30, 2003 9:26 pm
Posts: 2893
Location: Glasgow, Scotland
I think you might have tried to do too much in one class. The Responsibility Driven Design principle is to parcel out separate tasks in separate classes.

Image processing, file upload, and user interface are all part of one class rather than split into a network of objects - this looks like a program module rather than a single class.

If you do refactor with RDD in mind you can make some important gains: for example the image processor functions, in a separate class or classes, would now be free for re-use in other scripts.

Class methods look a little too large as well. Six lines per function is nice. Seven at a pinch. If you cut them down they can be stripped out and put together in new ways.

UML diagrams (explained somewhere on phppatterns.com can't remember where but you'll find lots of interesting stuff as you hunt around) can be very useful in working out an OOP design.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 25, 2004 11:41 pm 
Offline
Forum Contributor
User avatar

Joined: Fri Jan 24, 2003 4:27 am
Posts: 243
And you might like to change your code in the process function to something like this.
Multi-level nested if statements can often be avoided with return statments

Syntax: [ Download ] [ Hide ]
<?php

   function process($image = '0')

   {

      #checks that file was uploaded

      if(!file_exists($_FILES[$this->field_name][tmp_name]))

         return $this->error(1);



      #checks that the file isnt too large

      if($_FILES[$this->field_name][size]>$this->file_max_size)

         return $this->error(2);



      #checks to see if file type is allowed

      if(!in_array($_FILES[$this->field_name][type],$this->allow_types))

         return $this->error(3);



      #Repeat loop till you find an available file name

      for ($loop=1; file_exists($this->location); $loop++)

      {

         #create new file location

         $this->location = $this->dir."/".$loop."_".$this->file_prefix.$_FILES[$this->field_name][name];

         $this->thumb_location = $this->dir."/thumb_".$loop."_".$this->file_prefix.$_FILES[$this->field_name][name];

      }



      #processes file for image stuff

      if($image){

         $outcome = $this->process_image($image);

         if(!$image[skip_resize]){ # dont need to rename the orignal as we have skipped the resizing

            $this->location = $this->dir."/orig_".$loop."_".$this->file_prefix.$_FILES[$this->field_name][name];

         }

      }



      if($outcome){

         #returns any errors from the image function

         return $outcome;

      }else{

         #moves the original file from the tmp dir to where you want to store them

         if(!copy($_FILES[$this->field_name][tmp_name], $this->location)){

            return $this->error(4);

         }else{

            array_push($this->output, $this->location);

            #The upload was successful - the locations of all files uploaded are stored in $this->ouput.

            return "The file was successfully uploaded.";

         }

      }

   }

?>


And you can change this :
Syntax: [ Download ] [ Hide ]
if($_FILES[$this->field_name][type]=='image/jpeg' OR $_FILES[$this->field_name][type]=='image/pjpeg'){
with this :
Syntax: [ Download ] [ Hide ]
if(  in_array($_FILES[$this->field_name][type], array('image/jpeg','image/pjpeg'){


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 29, 2004 7:00 pm 
Offline
Site Admin
User avatar

Joined: Tue Dec 23, 2003 3:10 am
Posts: 11470
Location: Toronto
You seriously need run this script with E_ALL on, tons of undefined constants. Very nice class, seems to work well. Although I would have liked to see multple file uploading at once.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 29, 2004 8:59 pm 
Offline
DevNet Resident

Joined: Sun Jul 20, 2003 9:25 pm
Posts: 1150
Location: West Yorkshire, England
Since you can pass the class the name of the file field in the form you can just create several instances of the class with the different field names to upload multiple files - or write a subclass to do it. Its a fairly messy class anyway - as McGruff said - trying to do too much. It needs the image manipulation moving out and to focus on just uploading - maybe adding support to store the files in a database instead of a directory etc.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 03, 2005 2:41 pm 
Offline
Forum Newbie

Joined: Fri Jun 03, 2005 1:32 pm
Posts: 13


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 5 hours


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB® Forum Software © phpBB Group