The File Upload Class

Sometimes, you want to allow users of your site to upload files. These may be text, or images, or more exotic file types like MP3 audio or MPEG video. This is a more complex process than the file downloads we just discussed, but CI's file upload class takes care of most of the work for you. It also looks after some of the security issues. However, you should always think twice before allowing anyone to upload files to your site, and you may want to protect the upload page to prevent unauthorized users from doing it.

First, you need to allocate space to store the uploaded files—a folder or directory on your server. This must be set with the correct permissions, allowing users to write to it. (i.e. 777 on a Unix/ Linux system). Let's assume you call this folder uploads, and put it in your web root folder.

CI's file upload class is loaded with:

$this->load->library('upload'); Then you need to do three things:

• Write a controller to handle the uploads

• Provide your user with an upload form and a 'success' form

Let's take them in this order. First, set a series of defaults. You do this by creating a $config array.

Let's say you want to set the path to the upload directory you just created. For this, you need to say:

This line can either be in the controller you're about to write, or you can create a config/upload folder to contain it (this would be system/application/config/ upload.php) .

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

It's important to grasp the difference between these two ways of setting your defaults. If you set the defaults from the config/upload file, you don't need to specifically initialize the file upload class. Just load it and it will find the defaults for itself.

However, if you leave the defaults in the controller, you need to specify where they are when you load the class, using a second parameter to the loading function, like this:

where $config is the name of your array of defaults. (Don't try to set some defaults from the config/upload file and some from the controller!)

OK, so what's this fuss about defaults? So CI sets sensible defaults and you don't need to worry about them, right? Yes, but in this case you do. There are several important ones:

• The location of your upload file: CI doesn't make an assumption about this, you have to tell it.

• The types of file you want to allow your users to upload. This is set like this:

where the acceptable file types are specified with the pipe operator ( | ) between them. This setting would allow your site to upload the most popular image file types but would not allow it to upload audio files, for example. Setting this is a basic security measure: if you only want images to be uploaded, don't allow people to upload executable files or large MP3s.

Note that you must set a value before a file type can be uploaded: the default setting (i.e., no setting) allows no files to be uploaded.

• Max_size: it's sensible to set a limit on the maximum size of file, in kilobytes, that can be uploaded. You don't want malicious users filling up all your space. The default setting is 0, which sets no limit.

• Overwrite: if you already have a file in your uploads folder with the same name as the one that a user is uploading, should the old one be overwritten and lost forever? This depends on what your site is doing and why you are allowing uploads. CI defaults to 'FALSE', which means it doesn't overwrite the old file and the new file is saved under a new name. Explicitly set this default to 'TRUE', if you want new files to overwrite the old.

Note that CI doesn't automatically tell the user that it has renamed his or her file, which may possibly be confusing: see below for how to get at reports on the process.

• You can also set defaults for the size, width, and height of images, for encrypting the file, and for trimming blank spaces from its title.

Now that you have decided on your defaults, you need an upload controller. This is simple. Its role is to initialize the upload class, receive an upload from a user form, and then decide if it has been successful. If yes, it displays a report; if no, it returns to the upload form with a user message. At its simplest, it need only include one active function, do_upload(), like this:

/*constructor function to initialize controller and load the file upload class, plus the two other helpers it needs */

class Upload extends Controller {

function Upload() {

parent::Controller();

/*now the function which does all the work!*/

function do_upload() {

else

$this->upload->data()); $this->load->view('upload_success', $data);

This function needs an upload_form view, and an upload_success view. To build the first, use the form helper to build a normal form, pointing to the do_upload function of our 'upload' controller: but instead of opening it with:

echo form_open('upload/do_upload')

(as we did in the forms we built in Chapter 5), you open it with the form helper's multipart function:

echo form_open_multipart('upload/do_upload');

(Remember that we are writing code to produce HTML markup, so we need to echo it to the screen.)

Then, instead of the form helper's form_input function, use the form_upload function:

echo form_upload($data);

These two lines of code take care of a lot of really tedious stuff for you. Add as normal a submit button, and close the form.

echo form_submit('mysubmit', 'Submit Post!');

Pass your $view variable to a view and load it. Your view should also echo the $error variable, which the do_upload function passed when it loaded the view.

echo $error; You should now see something like this:

Browse.

upload |

Clicking on Browse allows the user to view the files on her or his own (local) computer, not your server. Once (s)he has selected a file, clicking on upload will call the upload controller, and the file will be transferred to the upload folder on your server.

Let's say I try to upload a text file. (Remember that our allowed file types are limited to 'gif | jpg | png'.) I now see:

The filetype you are attempting to upload is not allowed Browse... |

upload |

CI is reporting back the type of error to me: this is the $this->upload->display errors() function in the controller at work, adding an extra variable to the view.

You can also have CI report data on successful uploads to you. As you see, the controller we wrote just now calls a view called upload_success, if the upload is successful. The data passed to this view is the contents of the function $this->upload->data. This gives you a full array of information about the upload process: possibly more than you would want to display.

Let's say I uploaded a file called waltzer.jpg: the default report looks like this:

Your file was successfully uploaded!

♦ file_name: waltzerl.jpg

♦ file_path: E:/Kampplite/htdocs/packt2/uploads/

♦ full_path: E:/xamppUte/htdocs/packt2/uploads/waltzerl.jpg

♦ orig_natne: waltzer.jpg

♦ image_size_str: width="1600" height-" 1200" Upload Another File!

If you are using your site to create a rival to Flickr, for example, then this amount of information might confuse users who have uploaded their photographs! However, you can easily filter out any information that you don't want in the upload controller.

Please note, by the way, that I set the 'overwrite' default to 'FALSE' when configuring the file upload class to write this example. I then used the code to upload the image file waltzer.jpg — twice.

The previous screenshot is CI's report on the second successful upload. You'll see that the file has been renamed waltzer1.jpg. If I look in my upload directory, I can see both the original waltzer.jpg and the new waltzer1.jpg file. Depending on your application, you might want to compare the values for raw_name and orig_ name and inform the user that the file name has been changed.

CI does not compare the two files, only their names. If you are allowing several users to upload files, it is quite possible that two of them will inadvertently use the same filename for different files, and you may not want to lose the first. On the other hand, if you are using the site to upload reports that always have the same name, you may prefer only to have the latest version stored on the site—in which case overwriting is a simple way of saving space.

Here's that image, by the way. We're going to do a lot more with it in the next section.

Was this article helpful?

+2 0

Responses

  • Hamza
    Where exactly does codeigniter want the upload directory?
    9 years ago

Post a comment