views:

263

answers:

3

I'm making a page where the user upload a file. I want an if statement to create an $error variable if the file type is anything other jpg, gif, and pdf.

Here's my code:

$file_type = $_FILES['foreign_character_upload']['type']; //returns the mimetype

if(/*$file_type is anything other than jpg, gif, or pdf*/) {
  $error_message = 'Only jpg, gif, and pdf files are allowed.';
  $error = 'yes';
}

I'm having difficulty structuring the if statement. How would I say that?

+1  A: 

Put the allowed types in an array and use in_array().

$file_type = $_FILES['foreign_character_upload']['type']; //returns the mimetype

$allowed = array("image/jpeg", "image/gif", "application/pdf");
if(!in_array($file_type, $allowed)) {
  $error_message = 'Only jpg, gif, and pdf files are allowed.';
  $error = 'yes';
}
animuson
I'm afraid $file_type would contain something different from just "jpg" or "gif", but the rest is ok
Col. Shrapnel
Well, he didn't ask for help with the file_type so I didn't bother doing anything with it. I do believe the type part will return results such as "image/jpeg", "image/gif", and "application/pdf".
animuson
That's exactly what I was asking. Thanks alot animuson! Much appreciated!
zeckdude
+1  A: 

edit

I just realized that you want to allow PDF files as well. In that case check out PHP's Fileinfo class and functions. But as far as security goes, you still shouldn't rely on $_FILES[]['type'] :)

I'll leave the rest here in case it helps someone else who finds this question


For checking the mime type of the image, $_FILES[]['type'] could be unsafe. This data is sent by the browser and could be easily spoofed.

You should use the getimagesize() function if you only want to allow images to be uploaded (despite its maybe misleading name). This function won't just give you the size but all the data you will probably need about the image.

I used the following script in an image handling class:

private function load_image_data($image_file) {

    // Firstly, to disambiguate a loading error with a nonexistant file error,
    // check to see if the file actually exists.
    if( ! file_exists($image_file) ) {
        throw new Nonexistent_Image_Exception("The file '{$image_file}' does not exist");
    }

    // We're going to check the return value of getimagesize, so we don't
    // need any pesky warnings or notices popping up, since we're going to
    // stop execution of this function if something goes wrong.
    $image_data = @getimagesize($image_file);

    if( $image_data === false ) {
        throw new Load_Image_Exception("Could not get image data from '{$image_file}'");
    }

    $this->size = new Dimensions($image_data[0], $image_data[1]);
    $this->mime = $image_data['mime'];

}

Notice that getimagesize() returns an associative array containing a 'mime' index. The data here is reliable.

In another function I checked the mime type of the image and converted it to PNG with the appropriate GD function:

private function load_image($image_file) {

    // Suppress warning messages because we're going to throw an
    // exception if it didn't work instead.
    switch( $this->mime ) {
    case 'image/jpeg':
    case 'image/pjpeg':
        $this->image = @imagecreatefromjpeg($image_file);
        break;
    case 'image/gif':
        $this->image = @imagecreatefromgif($image_file);
        break;
    case 'image/png':
        $this->image = @imagecreatefrompng($image_file);
        break;
    default:
        throw new Invalid_Image_Exception("The image was of an invalid type");
    }

    if( $this->image === false ) {
        throw new Load_Image_Exception("Loading of image '{$image_file}' failed");
    }

}

You probably won't need to do all of this, but you can see what mime types appear for the filetypes you have specified. Notice that a jpeg could have two different mime types.

Hope this helps.

Carson Myers
Hmm, very interesting! Can I use this for pdf files as well?
zeckdude
I'm afraid I misread your question and skipped the 'pdf' part. I made an edit at the top pointing you towards some PHP functions for getting file information. I can't stress enough though how important it is to not trust data from the browser
Carson Myers
A: 

See also Zend Framework's Zend_File_Transfer_Adapter_Http and Zend_Form_Element_File. You can add multiple different validators like minimum image resolution, MIME type, minimum file size, allowed file extensions, etc.

raspi