DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Kenneth has posted 3 posts at DZone. View Full User Profile

Detecting File Type - The Ultimate Way In Php

07.01.2009
| 4905 views |
  • submit to reddit
        // description of your code here

<?php
function strhex($string)
 {
    $hex = "";
    $len = strlen($string);

    for($i = 0; $i < $len; ++$i)
     {
       $hex .= str_pad(dechex(ord($string[$i])), 2, 0, STR_PAD_LEFT);
     }
    return $hex;
 }

$data = file_get_contents($filename);

if(preg_match('/\.(jpg|jpeg|gif|png)/i', $filename, $matches))
 {
    $type = ($matches[1] === 'jpeg') ? 'jpg' : $matches[1];
 }
else
 {
     // Get the first 12 bytes of the file
     $hdr  = strhex($data[0].$data[1].$data[2].$data[3].$data[4].$data[5].$data[6].$data[7].$data[8].$data[9].$data[10].$data[11]);
     echo $hdr;

     // Match header of the file (Google it).
     if(preg_match('$/ffd8ffe0....4A46494600/i', $hdr))
      {
        // JPEG?
        $type = 'jpg';
      }
     elseif(preg_match('$/89504e470D0a1a0a/i', $hdr))
      {
        // PNG?
        $type = 'png';
      }
     elseif(preg_match('$/474946/i', $hdr))
      {
        // GIF?
        $type = 'gif';
      }
     else
      {
         // Unknown image type.
      }
 }
    

Comments

Kenneth Mccall replied on Fri, 2007/08/10 - 11:56am

[Bug] Regex was wrong. [Improved] file_get_contents - restricted to the first 12 bytes. Should improve performance. <?php function strhex($string) { $hex = ""; $len = strlen($string); for($i = 0; $i < $len; ++$i) { $hex .= str_pad(dechex(ord($string[$i])), 2, 0, STR_PAD_LEFT); } return $hex; } $data = file_get_contents($filename, FALSE, NULL, -1, 12); if(preg_match('/\.(jpg|jpeg|gif|png)/i', $filename, $matches)) { $type = ($matches[1] === 'jpeg') ? 'jpg' : $matches[1]; } else { // Get the first 12 bytes of the file // Could probably do strhex($data) - but this might be safer..? $hdr = strhex($data[0].$data[1].$data[2].$data[3].$data[4].$data[5].$data[6].$data[7].$data[8].$data[9].$data[10].$data[11]); echo $hdr; // Match header of the file (Google it). if(preg_match('/^ffd8ffe0....4A46494600/i', $hdr)) { // JPEG? $type = 'jpg'; } elseif(preg_match('/^89504e470D0a1a0a/i', $hdr)) { // PNG? $type = 'png'; } elseif(preg_match('/^474946/i', $hdr)) { // GIF? $type = 'gif'; } else { // Unknown image type. } }

Kenneth Mccall replied on Fri, 2007/08/10 - 11:56am

Only works if the file has the correct extension.. This determines type by looking at the first 12 bytes of the file (the file's header).

Snippets Manager replied on Tue, 2009/07/21 - 4:08pm

PHP has got a function for that already, its called pathinfo(). It returns an array of information about a file path, so say if you just wanted to test if the file was a specific type then you could just do this: $ext = pathinfo('path/to/file', PATHINFO_EXTENSION); // When you set an option, the function returns a string if ($ext === 'jpg') { // Do something if the file is a jpg } else if ($ext === 'png') { // Do something if the file is a png } else if ($ext === 'gif') { // Do something if the file a a gif } else { return false; }