tags:

views:

790

answers:

6

how can i check if a file is an mp3 file or image file, other than check each possible extension?

+4  A: 

You can identify image files using getimagesize.

To find out more about MP3 and other audio/video files, I have been recommended php-mp4info getID3().

Pekka
are you saying that i should check if a file is an image or not using getimagesize something like : if(!getimagesize(path)){print 'this file is not an image!';} ? getimagesize(); returns false if the file is not an image?
kmunky
+1 for this answer... the only way to be sure an image is an image is to use a library (in this case there are built in ones for images) that actually opens the file and parses it like you are suggesting. This way you prevent somebody renaming an .XLS to .GIF and uploading it.
TravisO
@kmunky: exactly. Check out the manual link to see what image types the function recognizes.
Pekka
i use this to check if a uploaded file is really a image: $tempFile = $_FILES['image']['tmp_name']; $image = getimagesize($tempFile); if ($image['mime']!=='image/jpeg'){ echo "error"; return; }
robertdd
+2  A: 

try mime_content_type()

<?php
echo mime_content_type('php.gif') . "\n";
echo mime_content_type('test.php');
?> 

Output:

image/gif

text/plain

Or better use finfo_file() the other way is deprecated.

Burntime
I am curious why this got a downvote? It's only deprecated as of 5.3
Gordon
The PHP docs say right on the first line that this function has been depreciated.
TravisO
right, that's why i'm asking you
kmunky
His question specifically says check the file type besides just checking the file extension, which is all mime_content_type does, it's basically a built in array of extensions, it has no idea what the file really is.
TravisO
+6  A: 

Native way to get the mimetype:

For PHP < 5.3 use mime_content_type()
For PHP > 5.3 use finfo_fopen()

Alternatives to get the MimeType are exif_imagetype and getimagesize, but these rely on having the appropriate libs installed. In addition, they will likely just return image mimetypes, instead of the whole list given in magic.mime.

While mime_content_type is removed from PHP5.3, it works fine below that version. E_STRICT won't even raise a notice about it being deprecated. If you don't want to bother about what is available on your system, just wrap all four functions into a proxy method that delegates the function call to whatever is available, e.g.

function getMimeType($filename)
{
    $mimetype = false;
    if(function_exists('finfo_fopen')) {
        // open with FileInfo
    } elseif(function_exists('getimagesize')) {
        // open with GD
    } elseif(function_exists('exif_imagetype')) {
       // open with EXIF
    } elseif(function_exists('mime_content_type')) {
       $mimetype = mime_content_type($filename);
    }
    return $mimetype;
}
Gordon
The PHP docs say right on the first line that this function has been depreciated.
TravisO
@TravisO: Deprecated in favor of finfo_open. And that is not natively available before 5.3. Given that the other two methods to get the mimetype rely on GD and Exif, which are not necessarily enabled, using mime_content_type is the only native way to do it.
Gordon
+2  A: 

You can use FileInfo module which is built into PHP since 5.3. If you are using a PHP version less than PHP 5.3, you can install it as a PECL extension:

After installation the finfo_file function will return file information.

PECL extension: http://pecl.php.net/package/fileinfo

PHP Documentation: http://www.php.net/manual/en/book.fileinfo.php

ctshryock
+2  A: 

You could use finfo like this:

$mime = finfo_open(FILEINFO_MIME, $path_to_mime_magic_file);
if ($mime ===FALSE) {
    throw new Exception ('Finfo could not be run');
}
$filetype = finfo_file($mime, $filename);
finfo_close($mime);

or if you have problems with finfo not being installed, or the mime magic file just not working (it works correctly on 3 out of our 4 servers - all identical OS and PHP installs) - then try using Linux's native file (don't forget to sanitise the filename though: in this example, I know the filename can be trusted as it's a PHP temporary filename in my test code):

ob_start();
system('file -i -b '.$filename);
$output = ob_get_clean();
$output = explode("; ", $output);
if (is_array($output)) {
     $filetype = trim($output[0]);
}

Then just pass the mime file type to a switch statement like:

switch (strtolower($filetype)) {
            case 'image/gif':
                return '.gif';
                break;
            case 'image/png':
                return '.png';
                break;
            case 'image/jpeg':
                return '.jpg';
                break;
            case 'audio/mpeg':
                return '.mp3';
                break;
}
return null;
Richy C.
+1  A: 

To find the mime type of a file I use the following wrapper function:

function Mime($path)
{
    $result = false;

    if (is_file($path) === true)
    {
        if (function_exists('finfo_open') === true)
        {
            $finfo = finfo_open(FILEINFO_MIME_TYPE);

            if (is_resource($finfo) === true)
            {
                $result = finfo_file($finfo, $path);
            }

            finfo_close($finfo);
        }

        else if (function_exists('mime_content_type') === true)
        {
            $result = preg_replace('~^(.+);.*$~', '$1', mime_content_type($path));
        }

        else if (function_exists('exif_imagetype') === true)
        {
            $result = image_type_to_mime_type(exif_imagetype($path));
        }
    }

    return $result;
}
Alix Axel