(PHP >= 5.3.0, PECL fileinfo >= 0.1.0)
finfo_file — Return information about a file
Prozeduraler Stil
Objektorientierter Stil
This function is used to get information about a file.
Fileinfo resource returned by finfo_open().
Name of a file to be checked.
One or disjunction of more Fileinfo constants.
For a description of contexts, refer to Stream Funktionen.
Returns a textual description of the contents of the filename argument, or FALSE if an error occurred.
Beispiel #1 A finfo_file() example
<?php
$finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
foreach (glob("*") as $filename) {
echo finfo_file($finfo, $filename) . "\n";
}
finfo_close($finfo);
?>
Das oben gezeigte Beispiel erzeugt eine ähnliche Ausgabe wie:
text/html image/gif application/vnd.ms-excel
I thought to use fileinfo to check if a file was gzip or bzip2. However, the mime type of a compressed file is "data" because compression is an encoding rather than a type.
gzip files begin with binary 1f8b.
bzip2 files begin with magic bytes 'B' 'Z' 'h'.
e.g.
<?php
$s = file_get_contents("somefilepath");
if ( bin2hex(substr($s,0,2)) == '1f8b' ) {/* could be a gzip file */}
if( substr($s,0,3) == 'BZh' ){/* could be a bzip2 file */}
?>
I am not an encoding expert. My only testing was using a few of my own encoded files.
OO (bit improved) version of the same thing
<?php
$file = '<somefile>';
$ftype = 'application/octet-stream';
$finfo = @new finfo(FILEINFO_MIME);
$fres = @$finfo->file($file);
if (is_string($fres) && !empty($fres)) {
$ftype = $fres;
}
?>
Another interresting feature of finfo_file on Windows.
This function can return empty string instead of FALSE for some file types (ppt for example). Therefore to be sure do a triple check of output result and provide default type just in case. Here is a sample code:
$ftype = 'application/octet-stream';
$finfo = @finfo_open(FILEINFO_MIME);
if ($finfo !== FALSE) {
$fres = @finfo_file($finfo, $file);
if ( ($fres !== FALSE)
&& is_string($fres)
&& (strlen($fres)>0)) {
$ftype = $fres;
}
@finfo_close($finfo);
}
Just an improvement on the sample Ryan Day posted - slightly off topic since this method does not use finfo_file but in some cases this method might be preferable.
The main change is the -format %m parameters given to the identify call. I would suggest using the full system path to identify i.e. /usr/bin/identify to be a little safer (the location may change from server to server though).
<?php
function is_jpg($fullpathtoimage){
if(file_exists($fullpathtoimage)){
exec("/usr/bin/identify -format %m $fullpathtoimage",$out);
//using system() echos STDOUT automatically
if(!empty($out)){
//identify returns an empty result to php
//if the file is not an image
if($out == 'JPEG'){
return true;
}
}
}
return false;
}
?>
FYI
contrary to the documentation, finfo_file seems to be returning a semicolon delimited string that contains not just the mime type but also the character set.
so
$finfo = finfo_open(FILEINFO_MIME);
echo(finfo_file($finfo, $my_file));
returns: text/plain; charset=us-ascii
it may be dependent on the magic file, but i'm too lazy to investigate further.
to check images on unix based systems its much better to use the identify command provided by image magic as it provides accurate results about all files
<?php
function is_jpg($fullpathtoimage){
if(file_exists($fullpathtoimage)){
exec("identify $fullpathtoimage",$out);
//using system() echos STDOUT automatically
if(!empty($out)){
//identify returns an empty result to php
//if the file is not an image
$info = $out[0];
$info = explode(' ',$out[0]);
//^IF THE FILENAME CONTAINS SPACES
//^THIS WILL NOT WORK...be creative
$type = $info[1];
if($type == 'JPEG'){
return true;
}
}
}
return false;
}
?>
identify can process all types of images that are web friendly
sample output:
./image/someimage.jpg JPEG 150x112 150x112+0+0 DirectClass 8-bit 4.54688kb
if you dont want to control the image name or want to support spaces use: escapeshellarg()
http://us2.php.net/manual/en/function.escapeshellarg.php
function links:
exec() -- http://us2.php.net/manual/en/function.exec.php
explode() -- http://us2.php.net/manual/en/function.explode.php
Tempting as it may seem to use finfo_file() to validate uploaded image files (Check whether a supposed imagefile really contains an image), the results cannot be trusted. It's not that hard to wrap harmful executable code in a file identified as a GIF for instance.
A better & safer option is to check the result of:
if (!$img = @imagecreatefromgif($uploadedfilename)) {
trigger_error('Not a GIF image!',E_USER_WARNING);
// do necessary stuff
}