read

CI's Upload Library

CodeIgniter's upload library allows you to specify allowable files on a case-by-case basis by simply crafting something like the following:

    $config['upload_path'] = './public/media/audio/';
    $config['allowed_types'] = 'mp3';
    $config['overwrite']= TRUE;
    $config['max_size']  = '5120';
    $this->load->library('upload', $config);

In this case, I specified that the allowable file types are mp3s (multiple types can be set by placing a bar (i.e. |) between each file type.

In order to ensure that the user is actually uploading an mp3, we check the file's mime type. If you check out your application/config/mimes.php file, you'll note that you can associate one or more mime types for each allowed_type.

This provides us with an incredible amount of granular control. CodeIgniter's boilerplate, while useful, will often need to be adjusted.

Tracking Down an Upload Failure

I recently built an application that allowed musicians to upload demo mp3 files for review by potential clients. I had a musician contact me saying that his files were getting rejected. When I uploaded the files and investigated the $_FILES global, I had one array element that looked like this:

  'name' => string 'If All My Heroes Are Losers.mp3' (length=41)
  'type' => string 'audio/mp3' (length=9)
  'tmp_name' => string '/private/var/tmp/php7AH5ES' (length=26)
  'error' => int 0
  'size' => int 4166380

Looks good, right? The type is correct, the file size is less than 5120 bytes. So what gives?

The function that actually actuates the upload is called do_upload and is part of the CI_Upload library, so let's head over there to see what's going on.

Of particular interest is the method, _file_mime_type which validates the file's mime type. As long as you are using PHP 5.3 or higher, CodeIgniter will use a fileinfo resource to determine the actual mime type. In this case, we see:

$mime = @finfo_file($finfo, $file['tmp_name']);

Despite what the $_FILES global showed under type, the actual mime type returned was audio/x-wav; charset=binary. A HA! This is a wav file masquerading as an mp3!

I have two choices here, I can probably add this to my mime type list in mimes.php as wav files are kosher in this regard, or I could explain to the musician that he has likely encoded his files incorrectly.

Blog Logo

Phil Birnie


Published

Image

Phil Birnie

Full Stack Web Developer from Columbus, Ohio

Back to Overview