Using the PHP Fileinfo extension

In my last post, I described how to install the Fileinfo PECL module on a Media Temple (dv) server, but I didn't really talk about what it does, why one might want to install it and how to use it.

The methods/functions in the Fileinfo PHP extension "try to guess the content type and encoding of a file by looking for certain magic byte sequences at specific positions within the file. While this is not a bullet proof approach, the heuristics used do a very good job."1 (Note that this module replaces the Mimetype module.)

The primary use I see for Fileinfo (and the reason I installed it last weekend!) is to test the MIME types of uploaded files against an array of allowed MIME types. I intend to use Fileinfo to supplement the standard check against the file type specified in the $_FILES array, since this is known to be unreliable (more on this in a future post!).

The Fileinfo extension is extremely simple to use. It can be implemented in either the object oriented or procedural style of programming, though my code examples will only demonstrate the former. As an object, we only need to worry about the constructor and two methods to test the MIME type; in the procedural style there are three functions to be aware of.

Here is a quick example from the PHP manual of how to use Fileinfo in the object oriented style:

$finfo = new finfo(FILEINFO_MIME, '/usr/share/misc/magic'); // return mime type ala mimetype extension
if (!$finfo) {
echo 'Opening fileinfo database failed';
/* get mime-type for a specific file */
$filename = '/usr/local/something.txt';
echo $finfo->file($filename);
/* close connection */

The above example should output text/plain, however there are a few "gotchas" I'll mention after I briefly discuss the various methods.

The Fileinfo constructor takes two optional parameters: a Fileinfo constant and the path to the "magic" database file. While the manual states that these are optional, I haven't had any luck getting Fileinfo to work on Media Temple without specifying both! The code I use:

$finfo = new finfo(FILEINFO_MIME, '/usr/share/file/magic');

The first method to know about is file, which is used to get the MIME type of a file. It takes one required and two optional parameters. The required parameter is a string file name:


The second method is close, which supposedly closes the resource created by the constructor.

As you can see, quite simple. However, as I mentioned above, not everything works as the documentation states! I'm not sure if this is a general problem with the module or simply the version I'm using (1.0.4 under PHP 5.2.6), but there are two errors:

  1. The constructor is supposed to return "a magic database resource on success or false on failure."2 In the procedural style it does, but in the object oriented style it always returns an object, so the if (!$finfo) { } condition in the example above always returns true. This is a problem if the path to the magic database file is wrong, because calling the file method without a magic database resource will throw an error.
  2. In both the object oriented and procedural styles, calling the close method triggers a fatal error. It seems the method/function simply isn't defined, despite what the documentation claims!

To solve these issues and to add a little functionality, I wrote a Fileinfo wrapper class that duplicates (some of) the native Fileinfo functionality. Unfortunately, the class is currently only available for PHP 5 and the documentation is poor (I intend to remedy both this weekend!).

To use this class, include it in your PHP file. The constructor, file and close methods all work similar to Fileinfo, only I provide a property to test for failure and my close method doesn't throw a fatal error! I also add a new method, test, that allows one to test a given file against an array of allowable MIME types.

Here's a sample of how to use it:

$finfo = new finformation(FILEINFO_MIME, '/usr/share/file/magic');
if ($finfo->ready) {
echo '<p>' . $finfo->file('themechanism-144x60.gif') . '</p>';
if ($finfo->test('themechanism-144x60.gif', array('image/gif'))) {
echo '<p>This is a valid file.</p>';
} else {
echo '<p>This is not a valid file.</p>';

If you have a file named "themechanism-144×60.gif" on your server and if it's a gif, this should output <p>image/gif</p><p>This is a valid file.</p>, otherwise it will output <p>This is not a valid file</p>.



4 thoughts on “Using the PHP Fileinfo extension

Leave a Reply