Wednesday 30th of July 2014 01:06:03 PM

Writing A File Upload Class using PHP

Author: BinaryStar
Version 1.1
Experience Level: Beginner



 

Introduction

Lately I have seen a ton of questions on the message board about uploading files to the server. It seems as if this is an epidemic that needs to be cured. I have written a PHP class for file uploads which some members of the message board have used and it helped to simplify their lives. Today we will attempt to write our own highly customizable file upload class. Before we get started get yourself a soda and something to munch on because this might take a while. Ready....(pause for the gathering of goodies)..okay let's begin.

What is a class and why do I need one?

Well to put it simply a class is a series of functions that work hand and hand to create an outcome. The reason a class works so great with uploading files is because there are a ton of functions one could write that would all depend on each other's outcome before the final result can be determined. For this reason we write a class instead of 10 functions and taking the time to validate each one.

Another beauty of a class is you can call any of the features within the class that you wish. For instance, with this class there will be 'x' amount of functions, all playing their role in the outcome of the actual upload process. If you wish to use this class to only verify a file's size and not upload it to the server, well you can. If you just wanted to get the file's extension and validate it, you could. That is the beauty of a class. If set up properly, classes are artwork, not just heavy amounts of code.

Before you write a class, or anything for that matter, we should try to plan ahead. Let us take some time and figure out what we need to make this class effective. We will need an arrangement of functions all verifying some sort of process and intermingling together. Let us take a step further and break down what individual functions we will be writing today.

  • Validation of file extensions
  • Validation of file sizes
  • Getting file sizes
  • Getting maximum file size allowment
  • Validation of users uploading files
  • Checking to see if the file exists
  • Setting the upload directory
  • Setting the upload log directory
  • Upload process with and without validation

If you are still asking yourself why you need a class the answer is simple. Ever write a great deal of code that works together to fulfill an outcome? Of course you have and you know how tedious it can be. Well with a class, the first time you write the class it will still be tedious and take some time, but after that first time you never have to write it again, all you need to do is call it and the rest is history. Classes along with functions will just make your life easier. With that being said, let us begin.

Do It With Class

PHP Example: (!)

<?php
class Upload_Files {

    var
$temp_file_name;
    var
$file_name;
    var
$upload_dir;
    var
$upload_log_dir;
    var
$max_file_size;
    var
$banned_array;
    var
$ext_array;
?>

The above snippet of code is the beginning of the class. You must start all classes with the word 'class'. Directly after the word 'class' is the class name. You can name this whatever you would like and stick with your naming conventions, but for this exercise I named it 'Upload_Class'. Following the class name is the opening bracket for the class. You need this to tell PHP - "Hey my class is starting, let's get it on". This may seem a bit remedial for some users, but not everyone is as comfortable with syntax as the more experienced scripters, so please bear with me.

Directly under the beginning of the class we must declare our variables for this class. Basically these are the variables that can be included from the outside of the class by the end user. Just like functions can take arguments, classes can as well, just with a bit different syntax. These lines are just telling the class that these variables can be defined by the user. Variables being used by the class must first be defined as 'var $variable_name'.

Function #1 (Validation of File Extensions)

PHP Example: (!)

<?php
function validate_extension() {
    
//SECTION #1
    
$file_name = trim($this->file_name);
    
$extension = strtolower(strrchr($file_name,"."));
    
$ext_array = $this->ext_array;
    
$ext_count = count($ext_array);

    
//SECTION #2
    
if (!$file_name) {
        return
false;
    } else {
        if (!
$ext_array) {
            return
true;
        } else {
            foreach (
$ext_array as $value) {
                
$first_char = substr($value,0,1);
                    if (
$first_char <> ".") {
                        
$extensions[] = ".".strtolower($value);
                    } else {
                        
$extensions[] = strtolower($value);
                    }
            }

            
//SECTION #3
            
foreach ($extensions as $value) {
                if (
$value == $extension) {
                    
$valid_extension = "TRUE";
                }                
            }

            
//SECTION #4
            
if ($valid_extension) {
                return
true;
            } else {
                return
false;
            }
        }
    }
}
?>

This first function will check to see if the file's extension is valid. How does it do that? Well let's take a look at each section of the code to find out. Firstly to use this function you must include both the file name and an allowable extension array, if you wish to accept all file extensions you do not need to send an extension array. At the end of this tutorial we will go over how to call this entire class and every function in the class, but for right now we are just going to examine the class itself so you can get a clear understanding of this powerful tool.

PHP Example: (!)

<?php
//SECTION #1
$file_name = trim($this->file_name);
$extension = strtolower(strrchr($file_name,"."));
$ext_array = $this->ext_array;
$ext_count = count($ext_array);
?>

Section #1
The first section of this function is just defining the variables to be used with the function.

PHP Example: (!)

<?php
//SECTION #2
if (!$file_name) {
    return
false;
} else {
    if (!
$ext_array) {
        return
true;
    } else {
        foreach (
$ext_array as $value) {
            
$first_char = substr($value,0,1);
                if (
$first_char <> ".") {
                    
$extensions[] = ".".strtolower($value);
                } else {
                    
$extensions[] = strtolower($value);
                }
        }
?>

Section #2
This section of the function starts our validation process for the file extension. First we check to see if a $file_name is present, if it is we continue, otherwise we exit the function and the result will be returned false, because with no file name, we have nothing to examine. Next we check to see if the $ext_array is present. If it is not, it will assume you are accepting all file extensions. Next we start our first foreach loop. This loop will make sure the file extensions begin with a period and are lowercase, if they are not they will be changed to reflect this and sent to another array named $extensions. Now that we have validated that we indeed have a file and a proper extension array we may continue.

PHP Example: (!)

<?php
//SECTION #3
foreach ($extensions as $value) {
    if (
$value == $extension) {
        
$valid_extension = "TRUE";
    }                
}
?>

Section #3
We are now starting yet another loop. We are using our newly defined and organized $extensions array as the focus in this loop. Within the loop is an if statement used to verify if the extension is valid. Basically the if statement says, if the file's extension matches one of the values extracted from the allowable extensions, set the $valid_extension variable to true. This is the core of our function, this section finds out if the file is acceptable or not.

PHP Example: (!)

<?php
            
//SECTION #4
            
if ($valid_extension) {
                return
true;
            } else {
                return
false;
            }
        }
    }
}
?>

Section #4
The last section of the function is just a snippet of code reading if the $valid_extension variable is present. If it is, the function returns true and the file is okay, otherwise the function returns false. There are also (3) closing brackets at the end of the code, (2) are for the above if-elseif statements and the latter one is for the closing of the function. There you have it, you have now just validated against file extensions. That wasn't too hard now was it.

Function #2 (Validation of File Size)

PHP Example: (!)

<?php
function validate_size() {
    
$temp_file_name = trim($this->temp_file_name);
    
$max_file_size = trim($this->max_file_size);

    if (!
$temp_file_name) {
        
$size = filesize($temp_file_name);
            if (
$size > $max_file_size) {
                return
false;                                                        
            } else {
                return
true;
            }
    } else {
        return
false;
    }    
}
?>

Since this function is considerably smaller than the last one, we will just run thru it as a whole instead of breaking into sections. The first (2) lines are just defining the $temp_file_name and $max_file_size which should be supplied by the end user upon the class call. Next we start our if-elseif statements. First we check to see if the $temp_file_name is present, if it is not, we exit the function and it returns false. If the $temp_file_name is present we extract the file's size and compare it to the $max_file_size allowed. If the file's size is greater than the max the function returns false, otherwise it returns true and the file size is valid. This is a pretty straight forward function.

Function #3 (Does This File Already Exist?)

PHP Example: (!)

<?php
function existing_file() {
    
$file_name = trim($this->file_name);
    
$upload_dir = $this->get_upload_directory();

    if (
$upload_dir == "ERROR") {
        return
true;
    } else {
        
$file = $upload_dir . $file_name;
        if (
file_exists($file)) {
            return
true;
        } else {
            return
false;
        }
    }    
}
?>

This function will check to see if the file trying to get uploaded already exists on the server. This function was added upon request and I did not go into it that much. Basically you should have some kind of pre-naming system that you use before you even think about uploading to the server. For instance when I allow users to upload to the server, there must be a record in a database somewhere about this file. So I take the id number from the database and rename the file they submitted to the id number. (ie. user submits hello_world.php, it gets changed to 452.php because this is the 452nd record in the DB) This is a very good naming system because it is extremely easy to delete and update records. There is no rename function included in this class but you could easily add one. With that being said, let us review this code.

The first (2) lines of this function are just declaring the $file_name and $upload_dir. Next we start our if-elseif statement. First we check to see if we have a valid upload directory. If not, we exit the function and return true. I know it seems backwards to return true when the file exists or there is an error but for this function it makes sense. The function's name is 'exisiting_file()', so if it returns true it is essentially saying that the file exists and should not be uploaded. If the upload directory is valid we continue to the next section of the if-elseif statement.

Now we figure the path to our file with the file name intact, ie. $file = $upload_dir . $file_name. Then we have a small snippet of code that uses the PHP function file_exists(). If the file exists, we return true, otherwise we return false and the file is okayed to be uploaded.

Function #4 (Extract The File's Size)

PHP Example: (!)

<?php
function get_file_size() {
    
//SECTION #1
    
$temp_file_name = trim($this->temp_file_name);
    
$kb = 1024;
    
$mb = 1024 * $kb;
    
$gb = 1024 * $mb;
    
$tb = 1024 * $gb;

        
//SECTION #2
        
if ($temp_file_name) {
            
$size = filesize($temp_file_name);
            if (
$size < $kb) {
                
$file_size = "$size Bytes";
            }
            elseif (
$size < $mb) {
                
$final = round($size/$kb,2);
                
$file_size = "$final KB";
            }
            elseif (
$size < $gb) {
                
$final = round($size/$mb,2);
                
$file_size = "$final MB";
            }
            elseif(
$size < $tb) {
                
$final = round($size/$gb,2);
                
$file_size = "$final GB";
            } else {
                
$final = round($size/$tb,2);
                
$file_size = "$final TB";
            }
        } else {
            
$file_size = "ERROR: NO FILE PASSED TO get_file_size()";
        }
        return
$file_size;
}
?>

This function will examine the file to extract the file's actual size formatted for the upload log file. The code is broken down into (2) sections to make it easier to break down for you.

PHP Example: (!)

<?php
    
//SECTION #1
    
$temp_file_name = trim($this->temp_file_name);
    
$kb = 1024;
    
$mb = 1024 * $kb;
    
$gb = 1024 * $mb;
    
$tb = 1024 * $gb;
?>

Section #1
The first section of this function is just defining your variables. We get the temporary name of the file as well as define file sizes for comparison purposes. The file sizes are defined in bytes.

PHP Example: (!)

<?php
    
//SECTION #2
    
if ($temp_file_name) {
        
$size = filesize($temp_file_name);
        if (
$size < $kb) {
            
$file_size = "$size Bytes";
        }
        elseif (
$size < $mb) {
            
$final = round($size/$kb,2);
            
$file_size = "$final KB";
        }
        elseif (
$size < $gb) {
            
$final = round($size/$mb,2);
            
$file_size = "$final MB";
        }
        elseif(
$size < $tb) {
            
$final = round($size/$gb,2);
            
$file_size = "$final GB";
        } else {
            
$final = round($size/$tb,2);
            
$file_size = "$final TB";
        }
    } else {
        
$file_size = "ERROR: NO FILE PASSED TO get_file_size()";
    }
    return
$file_size;
}
?>

Section #2
The second section of this function starts our validation and output process. First we check to if the $temp_file_name is valid, if not, the function returns an error, otherwise the function continues and tries to determine the file's actual size. Upon validation of the $temp_file_name we now get the file's size in bytes from the PHP function filesize(). We would like to have a readable output for our log file as well as our user. Users don't want to see 10240 bytes, they want to see 10 KB. So we set up a simple statement comparing the file's size against different file sizes to return our readable file size. The code is actually pretty self explanatory, it's just basic math.

Function #5 (Extract The Max File Size)

PHP Example: (!)

<?php
function get_max_size() {
    
$max_file_size = trim($this->max_file_size);
    
$kb = 1024;
    
$mb = 1024 * $kb;
    
$gb = 1024 * $mb;
    
$tb = 1024 * $gb;

    if (
$max_file_size) {
        if (
$max_file_size < $kb) {
            
$max_file_size = "max_file_size Bytes";
        }
        elseif (
$max_file_size < $mb) {
            
$final = round($max_file_size/$kb,2);
            
$max_file_size = "$final KB";
        }
        elseif (
$max_file_size < $gb) {
            
$final = round($max_file_size/$mb,2);
            
$max_file_size = "$final MB";
        }
        elseif(
$max_file_size < $tb) {
            
$final = round($max_file_size/$gb,2);
                
$max_file_size = "$final GB";
        } else {
            
$final = round($max_file_size/$tb,2);
            
$max_file_size = "$final TB";
        }
    } else {
        
$max_file_size = "ERROR: NO SIZE PARAMETER PASSED TO  get_max_size()";
    }
        return
$max_file_size;
}
?>

We will not be breaking this function down into sections because it is almost exact to the previous function. The only thing different is it just returns a readable maximum file size to the user. This function would be great to call in the event of the user trying to upload a file that is too large. You could write an error to the screen and use this function to display the maximum file size allowed in a readable format. Again at the end of this tutorial I will breakdown how to call the class and each function, as well as show you examples of why you would call individual functions. Let us move on to Function #6.

Function #6 (Validation of The User)

PHP Example: (!)

<?php
function validate_user() {
    
//SECTION #1
    
$banned_array = $this->banned_array;
    
$ip = trim($_SERVER['REMOTE_ADDR']);
    
$cpu = gethostbyaddr($ip);
    
$count = count($banned_array);

    
//SECTION #2
    
if ($count < 1) {
        return
true;
    } else {
        foreach(
$banned_array as $key => $value) {
            if (
$value == $ip ."-". $cpu) {
                return
false;
            } else {
                return
true;
            }
        }
    }
}
?>

This function will validate against the user trying to upload. The great thing about this class is you can block people from uploading to your server, no matter username no matter anything. It uses a technique of grabbing the IP address as well as the user's host. It combines them together and gives a proper id. Everytime a user uploads a file this information as well as the file name, size, date, and time are written to a text file on the server. If you ever have a problem with someone uploading viruses, you can delete the file, check to see who uploaded the file, and add the IP - Host Name to your banned user's list. If the user is ever found on the list, he/she will not be able to upload files. The code has been broken down into two sections, let's take a detailed look at each section.

PHP Example: (!)

<?php
function validate_user() {
    
//SECTION #1
    
$banned_array = $this->banned_array;
    
$ip = trim($_SERVER['REMOTE_ADDR']);
    
$cpu = gethostbyaddr($ip);
    
$count = count($banned_array);
?>

Section #1
Section one is just defining all your variables going to be used in this particular function. First we define our banned array. If you don't have anyone on your banned array list, you can either send a blank array or just don't send this variable with the class. If the banned array is not found, the function will assume that everyone is allowed to upload and no checks will take place. Secondly we are gathering the user's IP address found in REMOTE_ADDR. Next we get the user's host. Get host is supposed to mean the person's internet host/provider (ISP). Our last variable is just defining the number of elements within the banned users array.

PHP Example: (!)

<?php
    
//SECTION #2
    
if ($count < 1) {
        return
true;
    } else {
        foreach(
$banned_array as $key => $value) {
            if (
$value == $ip ."-". $cpu) {
                return
false;
            } else {
                return
true;
            }
        }
    }
}
?>

Section #2
The second section starts our validation process. It first checks to see if you have anyone in your banned users list. If not then the function returns true, meaning the user can upload. Otherwise the a foreach() loop is started for the array and the value of each key in the array is compared to the $ip - $cpu name. If these (2) values match, the function returns false and the user will NOT be able to upload files, otherwise it returns true and the user will can go about his/her business. After the validation process is complete all ending brackets are aligned with their counterpart and everything closes properly.

Function #7 (Verify The Upload Directory)

PHP Example: (!)

<?php
function get_upload_directory() {
    
//SECTION #1
    
$upload_dir = trim($this->upload_dir);

    
//SECTION #2
    
if ($upload_dir) {
        
$ud_len = strlen($upload_dir);
        
$last_slash = substr($upload_dir,$ud_len-1,1);
            if (
$last_slash <> "/") {
                
$upload_dir = $upload_dir."/";
            } else {
                    
$upload_dir = $upload_dir;
            }

        
//SECTION #3
        
$handle = @opendir($upload_dir);
            if (
$handle) {
                
$upload_dir = $upload_dir;
                
closedir($handle);
            } else {
                
$upload_dir = "ERROR";
            }
    } else {
        
$upload_dir = "ERROR";
    }
    return
$upload_dir;
} way out to the right edge of the browser window. This line will also inherit the green color of the text and so really punch up the fact that the title and navigation buttons are separate from the rest of the page.

Now that this is all done, we need to link the style sheet into the site's pages. The above declarations are collected into a single file, which is saved to a file with the URL http://www.mycomp.com/style/site.css. Then all of the site's pages are modified so that their HEAD element contains the following:
?>


This function will take the upload directory that you set forth and validate it. First it wants to see if the directory you entered was formatted correctly and then it will check to see if the directory exists. Pretty handy feature just in case you miss a keystroke. I broke this code down into (3) sections so I could better explain each key section.

PHP Example: (!)

<?php
    
//SECTION #1
    
$upload_dir = trim($this->upload_dir);
?>

Section #1
You are probably pretty sick of section #1 by now, but this section #1 is no different from any other section #1. If you haven't guessed by now, we are defining variables. I know, I know, but please try to keep you excitement at a minimum so we can finish this tutorial. The only thing we are defining here is the upload directory which should be set by you.

PHP Example: (!)

<?php
    
//SECTION #2
    
if ($upload_dir) {
        
$ud_len = strlen($upload_dir);
        
$last_slash = substr($upload_dir,$ud_len-1,1);
            if (
$last_slash <> "/") {
                
$upload_dir = $upload_dir."/";
            } else {
                    
$upload_dir = $upload_dir;
            }
?>

Section #2
This section again starts our validation process for verifying the upload directory is in working condition. First it checks to see that the upload directory is present. If it is the function will proceed, otherwise it shoots to the bottom and returns an invalid file directory to you, the user. Next we find the directory length using PHP's very own strlen(). The reason for doing this is we need to find the length of the string to extract the last character from the string. So next we use PHP's substr() function to extract the last character from the upload directory string. You will notice ($last_slash = substr($upload_dir,$ud_len-1,1);) that we are subtracting (1) from the length of the directory string, and we have good reason to do this. See we want to extract the last character off of the upload directory. The strlen() function counts the number of characters starting with '1', but when you count character places in a string you start with '0', hence the minus '1' from the overall length. If we did not do this, we would not select the last character, we would select nothing at all.

The reason for selecting the last character is simple. We need to see if it ends in a backslash. If it does not, we must add one for the function to work properly. So we set a variable of $last_slash which selects the last character, if that last character does not equal a backslash, we add one for the user, otherwise we do nothing.

PHP Example: (!)

<?php
        
//SECTION #3
        
$handle = @opendir($upload_dir);
            if (
$handle) {
                
$upload_dir = $upload_dir;
                
closedir($handle);
            } else {
                
$upload_dir = "ERROR";
            }
    } else {
        
$upload_dir = "ERROR";
    }
    return
$upload_dir;
}
?>

Section #3
In this final section we validate the upload directory. First we set our handle for opening the directory. Then we see if the handle will indeed open. If it does open we close the directory and return the upload directory name, otherwise we return an error to tell the user that the directory is invalid. After all validations have taken place we close all of our brackets and move forth.

*You may notice the @ symbol in front of the opendir() function. This symbol is used to suppress all errors associated with a function. See, if the upload directory is invalid, the opendir() function would produce an error because it gets confused, but we do not want the user to see this error, we want to suppress it so it does not conflict with our code.

Function #8 (Verify The Upload Log Directory)

PHP Example: (!)

<?php
function get_upload_log_directory() {
    
$upload_log_dir = trim($this->upload_log_dir);
    if (
$upload_log_dir) {
        
$ud_len = strlen($upload_log_dir);
        
$last_slash = substr($upload_log_dir,$ud_len-1,1);
            if (
$last_slash <> "/") {
                
$upload_log_dir = $upload_log_dir."/";
            } else {
                
$upload_log_dir = $upload_log_dir;
            }
            
$handle = @opendir($upload_log_dir);
                if (
$handle) {
                    
$upload_log_dir = $upload_log_dir;
                    
closedir($handle);
                } else {
                    
$upload_log_dir = "ERROR";
                }
    } else {
        
$upload_log_dir = "ERROR";
    }
    return
$upload_log_dir;
}
?>

We will not be breaking down this function. The reason for this is because it is exactly the same function we just went over except that it validates and returns the upload log directory. What is the upload log directory? This is the directory that you specify upon the class call to place all log files into. Everytime a user uploads a file, a .txt file is written to the server with today's date. If a file already exists for today's date we just append the data to the end, otherwise we start a new file.

The reason for doing this is to see who is uploading what and when. If somebody uploads a virus you will be able to track that user down and enter him/her onto your banned users list. This is a great function to have in any class or script for that matter, that deals with interaction between the public and the server.

Function #9 (Upload The File With No Validation)

PHP Example: (!)

<?php
function upload_file_no_validation() {
    
//SECTION #1
    
$temp_file_name = trim($this->temp_file_name);
    
$file_name = trim(strtolower($this->file_name));
    
$upload_dir = $this->get_upload_directory();
    
$upload_log_dir = $this->get_upload_log_directory();
    
$file_size = $this->get_file_size();
    
$ip = trim($_SERVER['REMOTE_ADDR']);
    
$cpu = gethostbyaddr($ip);
    
$m = date("m");
    
$d = date("d");
    
$y = date("Y");
    
$date = date("m/d/Y");
    
$time = date("h:i:s A");

    
//SECTION #2
    
if (($upload_dir == "ERROR") OR ($upload_log_dir == "ERROR")) {
        return
false;
    } else {
        if (
is_uploaded_file($temp_file_name)) {
            if (
move_uploaded_file($temp_file_name,$upload_dir . $file_name)) {
                
$log = $upload_log_dir.$y."_".$m."_".$d.".txt";
                
$fp = fopen($log,"a+");
                
fwrite($fp,"
$ip-$cpu | $file_name | $file_size | $date | $time"
);
                
fclose($fp);
                return
true;
            } else {
                return
false;    
            }
        } else {
            return
false;
        }
    }
}
?>

This is one of  the two key functions in this class. This function and the one of next page will actually attempt to upload your file. Hallelujah, praise the Lord, after 8 preliminary functions and 'x' amount of lines of code, we are now getting to the good stuff. This function will upload your file with no file or user validation. The only thing it validates are the (2) directories for uploading. If these are incorrect, the file will not be uploaded. If you don't care about file sizes, types, or users, or even if the file already exists, then use this function to upload your script.

This function is broken down into (2) parts to help simplify the process. Let's take a glance at what might go on inside a function like this. (The build up...)

PHP Example: (!)

<?php
    
//SECTION #1
    
$temp_file_name = trim($this->temp_file_name);
    
$file_name = trim(strtolower($this->file_name));
    
$upload_dir = $this->get_upload_directory();
    
$upload_log_dir = $this->get_upload_log_directory();
    
$file_size = $this->get_file_size();
    
$ip = trim($_SERVER['REMOTE_ADDR']);
    
$cpu = gethostbyaddr($ip);
    
$m = date("m");
    
$d = date("d");
    
$y = date("Y");
    
$date = date("m/d/Y");
    
$time = date("h:i:s A");
?>

Section #1
The function must define (12) different variables to get this party started. A list of variables is below with a short description of what what each one represents.

  • $temp_file_name = The temporary file name taken from the file that needs to be uploaded.
  • $file_name = The actual file name taken from the file that needs to be uploaded.
  • $upload_dir = The upload directory returned by the get_upload_directory() function.
  • $upload_log_dir = The upload directory returned by the get_upload_log_directory() function.
  • $file_size = The readable file size returned from the get_file_size() function.
  • $ip = The user's IP address.
  • $cpu = The user's internet host or (ISP)
  • $m = The current month in (2) digit format. (ie. 01)
  • $d = The current day in (2) digit format. (ie. 01)
  • $y = The current year in (4) digit format. (ie. 2003)
  • $date = Today's date as 01/01/2003
  • $time = The current time as 11:12:56 AM
PHP Example: (!)

<?php
    
//SECTION #2
    
if (($upload_dir == "ERROR") OR ($upload_log_dir == "ERROR")) {
        return
false;
    } else {
        if (
is_uploaded_file($temp_file_name)) {
            if (
move_uploaded_file($temp_file_name,$upload_dir . $file_name)) {
                
$log = $upload_log_dir.$y."_".$m."_".$d.".txt";
                
$fp = fopen($log,"a+");
                
fwrite($fp,"
$ip-$cpu | $file_name | $file_size | $date | $time"
);
                
fclose($fp);
                return
true;
            } else {
                return
false;    
            }
        } else {
            return
false;
        }
    }
}
?>

Section #2
This section of the code is where all the magic happens. It starts the validation and upload process. First it checks to make sure that the upload directories are valid, if they are not, the function returns false and exits, otherwise we continue to the next validation process.

Now we make sure that the file got uploaded to the temp directory. See in your php.ini file there is a section that asks for temp upload directory, this is where the file gets uploaded to. After it is uploaded we must take it from this directory and move it to the correct directory. So we first check to make sure it got uploaded to the temp directory using the is_uploaded_file() function. If it did we continue, otherwise the function returns false and exits.

Now we must check to see if the file was able to be moved from the temp directory to the correct directory with the move_uploaded_file() function. If it was then the upload is complete, the function returns true, and an entry is written in today's log file. Again a log file is kept for every single day a file is uploaded. Each log file will be named by today's date. (ie. 07192003.txt) If a file already exists we just append the data to the end of the file, otherwise we start a new file. In each log file the information kept is the ip address, the internet provider, the file name, file size, upload date, and upload time separated by '|'.

If the moving of the file fails the function will return false and then exit. That is all there really is to uploading a file. The actual upload process is easy, it is just all the variables that can and will take place that you have to account for. Let's move on to our last function for this class.

Function #10 (Upload The File With Validation)

PHP Example: (!)

<?php
function upload_file_with_validation() {
    
//SECTION #1
    
$temp_file_name = trim($this->temp_file_name);
    
$file_name = trim(strtolower($this->file_name));
    
$upload_dir = $this->get_upload_directory();
    
$upload_log_dir = $this->get_upload_log_directory();
    
$file_size = $this->get_file_size();
    
$ip = trim($_SERVER['REMOTE_ADDR']);
    
$cpu = gethostbyaddr($ip);
    
$m = date("m");
    
$d = date("d");
    
$y = date("Y");
    
$date = date("m/d/Y");
    
$time = date("h:i:s A");
    
$existing_file = $this->existing_file();    //<-Add On
    
$valid_user = $this->validate_user();        //<-Add On
    
$valid_size = $this->validate_size();        //<-Add On
    
$valid_ext = $this->validate_extension();    //<-Add On

    //SECTION #2
    
if (($upload_dir == "ERROR") OR ($upload_log_dir == "ERROR")) {
        return
false;
    }
    elseif ((((!
$valid_user) OR (!$valid_size) OR (!$valid_ext) OR ($existing_file)))) {
        return
false;
    } else {
        if (
is_uploaded_file($temp_file_name)) {
            if (
move_uploaded_file($temp_file_name,$upload_dir . $file_name)) {
                
$log = $upload_log_dir.$y."_".$m."_".$d.".txt";
                
$fp = fopen($log,"a+");
                
fwrite($fp,"
$ip-$cpu | $file_name | $file_size | $date | $time"
);
                
fclose($fp);
                return
true;
            } else {
                return
false;
            }
        } else {
            return
false;
        }
    }
}
?>

This function is exactly the same thing as the one on the last page except it adds an additional 6 lines of code. There are (4) new variables under section #1. Each one is listed below with a short description.

  • $existing_file = Returns true if the current file name already exists, false if not.
  • $valid_user = Returns the outcome of if the user is valid or not.
  • $valid_size = Lets the function know if the file size is valid.
  • $valid_ext = Calls the validate_extension() function to validate the file's extension.

These (4) lines are needed so we can validate whether or not the file should be allowed to be uploaded. The other line of code that is added is in Section #2 and listed below.

PHP Example: (!)

<?php
    
elseif ((((!$valid_user) OR (!$valid_size) OR (!$valid_ext) OR ($existing_file)))) {
        return
false;
?>

This is our bread and butter of the validation process. If checks to see if the user is valid, the file size is valid, the file extension is valid, and if the file already exists on the server. If everything checks out okay, it goes thru the same process described on the previous page to upload the file and writes a new line to the log file for that date. You could break this function down more to see which section failed if any, so feel free to expand as much as you want. Now all we have to do is call the class.

Calling The Class

Now that we did all that work, let's put this thing to some use. The best thing about this process is after you wrote the class, you never need to do it again. You can just include the class in your file using the include() function and call it. Instead of coding hundreds of lines each time. Now you can code a miniscle amount. Below is the process for calling the class.

PHP Example: (!)

<?php
//SECTION #1
$upload_class = new Upload_Files;
$upload_class->temp_file_name = trim($_FILES['upload']['tmp_name']);
$upload_class->file_name = trim(strtolower($_FILES['upload']['name']));
$upload_class->upload_dir = "uploads/";
$upload_class->upload_log_dir = "uploads/upload_logs/";
$upload_class->max_file_size = 524288;
$upload_class->banned_array = array("");
$upload_class->ext_array = array(".jpg",".gif",".jpeg",".png");

//SECTION #2
$valid_ext = $upload_class->validate_extension();
$valid_size = $upload_class->validate_size();
$valid_user = $upload_class->validate_user();
$max_size = $upload_class->get_max_size();
$file_size = $upload_class->get_file_size();
$upload_directory = $upload_class->get_upload_directory();
$upload_log_directory = $upload_class->get_upload_log_directory();
$upload_file = $upload_class->upload_file_with_validation();
?>

Section #1
In section one we must start the class and define our class variables. When you are starting a new instance of a class you must set a variable to the class. In this case our main class variable is $upload_class, then we start the class. (new Upload_Files) Just type the word new to let PHP know you are starting a new class and call the class name. Next we must define all of our class variables. To define variables we must start with our main class variable, in this case $upload_class. You have to let PHP know that you want this variable to be sent to the class and just not defined in the script. Remember back in the very beginning of the class, the variables that were defined, well now we will activate them. Let's have a quick look at each variable.

  • $upload_class->temp_file_name = trim($_FILES['upload']['tmp_name']); [set the temp file name]
  • $upload_class->file_name = trim(strtolower($_FILES['upload']['name'])); [set the actual file name]
  • $upload_class->upload_dir = "uploads/"; [set the upload directory]
  • $upload_class->upload_log_dir = "uploads/upload_logs/"; [set the upload log directory]
  • $upload_class->max_file_size = 524288; [set the max file size - .5MB or 512KB]
  • $upload_class->banned_array = array(""); [set the banned users array]
  • $upload_class->ext_array = array(".jpg",".gif",".jpeg",".png"); [set the acceptable file extensions]

You would not have to define every variable if you are not planning on using the validation scripts. If you are just going to upload, you only need the first (4) variables defined instead of all (7). Also remember if you do not have a banned users list, you do not have to define one and if you are going to accept all file extensions there is no need to send that variable either.

PHP Example: (!)

<?php
//SECTION #2
$valid_ext = $upload_class->validate_extension();
$valid_size = $upload_class->validate_size();
$valid_user = $upload_class->validate_user();
$max_size = $upload_class->get_max_size();
$file_size = $upload_class->get_file_size();
$upload_directory = $upload_class->get_upload_directory();
$upload_log_directory = $upload_class->get_upload_log_directory();
$upload_file = $upload_class->upload_file_with_validation();
?>

Section #2
The second section calls all the functions in the class. There is no need no call all the functions, I just wanted to show you that you could. A good reason to call all the functions is that you could setup a message return system. By that I mean you could say if !$valid_ext and return an error message to the user stating the file extension is incorrect. You could just call the $file_size and return that number to the user. The only function you need to call to upload files is the last line starting with $upload_file. If you are going to call the function with validation use the last line above, otherwise use the one below.

PHP Example: (!)

<?php
$upload_file
= $upload_class->upload_file_with_no_validation();
?>

Could there possibly be more information. Let's move to our final page and see what is in store.

Congratulations - You're a Class Act!

Pat yourself on the back, you just made it thru a very difficult process. If it doesn't really make sense yet, don't fret it might take a while to sink in. The best thing to do is read thru this tutorial a few times, even print it out for all the help you will need. The entire script is in a zip file below with an extraordinary amount of comments to help simplify the process. If you did not understand classes in general and went ahead with this tutorial, well then God bless you, and I hope classes are a bit more clear for you now. I am going to leave you with a sample code you could use on your page using this class. I am not going to explain this last code, you should be able to figure it out by now. It will also be included in the zip file for download.

*NOTE: If you are trying to validate against multiple uploads, just set a loop for the number of uploads you have and place all the class calling code within the loop. This will then execute the class over and over until the loop and every file has been processed.

PHP Example: (!)

<?php
$upload_class
= new Upload_Files;
$upload_class->temp_file_name = trim($_FILES['upload']['tmp_name']);
$upload_class->file_name = trim(strtolower($_FILES['upload']['name']));
$upload_class->upload_dir = "uploads/";
$upload_class->upload_log_dir = "uploads/upload_logs/";
$upload_class->max_file_size = 5242880;
$upload_class->banned_array = array("");
$upload_class->ext_array = array(".zip",".rar",".ace",".tar");

$valid_ext = $upload_class->validate_extension();
$valid_size = $upload_class->validate_size();
$valid_user = $upload_class->validate_user();
$max_size = $upload_class->get_max_size();
$file_size = $upload_class->get_file_size();
$file_exists = $upload_class->existing_file();

    if (!
$valid_ext) {
        
$result = "The file extension is invalid, please try again!";
    }
    elseif (!
$valid_size) {
        
$result = "The file size is invalid, please try again! The maximum file size is: $max_size and your file was: $file_size";
    }
    elseif (!
$valid_user) {
        
$result = "You have been banned from uploading to this server.";
    }
    elseif (
$file_exists) {
        
$result = "This file already exists on the server, please try again.";
    } else {
        
$upload_file = $upload_class->upload_file_with_validation();
        if (!
$upload_file) {
            
$result = "Your file could not be uploaded!";
        } else {
            
$result = "Your file has been successfully uploaded to the server.";
        }
    }
?>


Tutorial Revision History:

Another simple rule. This one keeps floating elements from floating all the way to the top of the document. The correct behavior is illustrated in Figure 8-33.

Figure 8-33

Figure 8-33. Unlike balloons, floated elements can't float upward

5. A floating element's top may not be higher than the top of any earlier floating or block-level element.

Similar to rule 4, this keeps a floated element from floating all the

The second problem is a little more fundamental: there are nostandard color values for these names. Declaring that an elementshould be colored orange doesn't mean thatdifferent browsers, or even the same browser running on differentplatforms, will produce exactly the same shade of orange. With thesixteen standard colors, there is at least some hope that they willappear as similar as possible, because the color values for thesesixteen are defined. Beyond those, all bets are off. Browsers mayimplement similar shades for the same color name, or they may not;the differences may be imperceptible to the eye, or so obvious that