Detecting Mime Type in PHP

PHP: How to properly check MIME type of a file?

To get MIME type, developers generally depend on $_FILES['input_name']['type']. But this is absolutely vulnerable. Because a malicious user can set one of image/jpg, image/png, image/gif etc. MIME types to a file that is not actually an image. In that case, the malicious user may get your script pass to upload other files instead of an image and execute your script for their purposes which is dangerous.

So I recommend that you not depend on the following snippet to get MIME of a file

$_FILES['input_name']['type'];

Rather I would recommend that you use this mime_content_type() function to get MIME type but with the help of other PHP's built-in functions. And that is is_uploaded_file() function. What it does is:

This is useful to help ensure that a malicious user hasn't tried to
trick the script into working on files upon which it should not be
working--for instance, /etc/passwd.

This sort of check is especially important if there is any chance that
anything done with uploaded files could reveal their contents to the
user, or even to other users on the same system.

So to make this function work properly it needs a specific argument. Check out the code below:

if (is_uploaded_file($_FILES['input_name']['tmp_name'])) {
// Do other stuff.
}

This function returns true on success, false otherwise. So if it returns true then you're ok with the file. Thanks to this function. Now mime_content_type() function comes into play. How? Look at the code below:

if (is_uploaded_file($_FILES['input_name']['tmp_name'])) {
// Notice how to grab MIME type.
$mime_type = mime_content_type($_FILES['input_name']['tmp_name']);

// If you want to allow certain files
$allowed_file_types = ['image/png', 'image/jpeg', 'application/pdf'];
if (! in_array($mime_type, $allowed_file_types)) {
// File type is NOT allowed.
}

// Set up destination of the file
$destination = '/path/to/move/your/file/';

// Now you move/upload your file
if (move_uploaded_file ($_FILES['input_name']['tmp_name'] , $destination)) {
// File moved to the destination
}
}

BTW, for novice, do not try remote URL with this function to get MIME type. The code below will not work:

mime_content_type('http://www.example.com/uploads/example.png');

But the one below would work:

mime_content_type('/source/to/your/file/etc.png');

Hope you would enjoy uploading files from now on.

Getting mime type from file name in php

If you check the documentation, you can see that you are not doing anything wrong.
But if you do a bit more research:

https://stackoverflow.com/a/3664655/3784145

you can see that the mime type you get is correct, but the extension doesn't need to match with the mime type as explained here:

http://nl3.php.net/manual/en/function.mime-content-type.php#85879

I would therefore use the files suffix to determine the files mime type.
(as seen in the first example)

Detecting MIME type in PHP

Have you looked into this PEAR package?

http://pear.php.net/package/MIME_Type

How to detect MIME type of plain text files: CSS, Javascript, ini, sql?

Since I didn't find a proper library, I wrote my own magic file that detects all of my test files properly.

My application first tries my custom magic file for detection and falls back to the normal/system magic file if no type is detected.

The code it on github, see https://github.com/cweiske/MIME_Type_PlainDetect .
The magic file is at data/programming.magic and can be used with file -f programming.magic /path/to/source

Correct way to detect mime type in php

Based on this I've ported it to PHP:

function getMicrosoftOfficeMimeInfo($file) {
$fileInfo = array(
'word/' => array(
'type' => 'Microsoft Word 2007+',
'mime' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'extension' => 'docx'
),
'ppt/' => array(
'type' => 'Microsoft PowerPoint 2007+',
'mime' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'extension' => 'pptx'
),
'xl/' => array(
'type' => 'Microsoft Excel 2007+',
'mime' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'extension' => 'xlsx'
)
);

$pkEscapeSequence = "PK\x03\x04";

$file = new BinaryFile($file);
if ($file->bytesAre($pkEscapeSequence, 0x00)) {
if ($file->bytesAre('[Content_Types].xml', 0x1E)) {
if ($file->search($pkEscapeSequence, null, 2000)) {
if ($file->search($pkEscapeSequence, null, 1000)) {
$offset = $file->tell() + 26;
foreach ($fileInfo as $searchWord => $info) {
$file->seek($offset);
if ($file->bytesAre($searchWord)) {
return $fileInfo[$searchWord];
}
}
return array(
'type' => 'Microsoft OOXML',
'mime' => null,
'extension' => null
);
}
}
}
}

return false;
}

class BinaryFile_Exception extends Exception {}

class BinaryFile_Seek_Method {
const ABSOLUTE = 1;
const RELATIVE = 2;
}

class BinaryFile {
const SEARCH_BUFFER_SIZE = 1024;

private $handle;

public function __construct($file) {
$this->handle = fopen($file, 'r');
if ($this->handle === false) {
throw new BinaryFile_Exception('Cannot open file');
}
}

public function __destruct() {
fclose($this->handle);
}

public function tell() {
return ftell($this->handle);
}

public function seek($offset, $seekMethod = null) {
if ($offset !== null) {
if ($seekMethod === null) {
$seekMethod = BinaryFile_Seek_Method::ABSOLUTE;
}
if ($seekMethod === BinaryFile_Seek_Method::RELATIVE) {
$offset += $this->tell();
}
return fseek($this->handle, $offset);
} else {
return true;
}
}

public function read($length) {
return fread($this->handle, $length);
}

public function search($string, $offset = null, $maxLength = null, $seekMethod = null) {
if ($offset !== null) {
$this->seek($offset);
} else {
$offset = $this->tell();
}

$bytesRead = 0;
$bufferSize = ($maxLength !== null ? min(self::SEARCH_BUFFER_SIZE, $maxLength) : self::SEARCH_BUFFER_SIZE);

while ($read = $this->read($bufferSize)) {
$bytesRead += strlen($read);
$search = strpos($read, $string);

if ($search !== false) {
$this->seek($offset + $search + strlen($string));
return true;
}

if ($maxLength !== null) {
$bufferSize = min(self::SEARCH_BUFFER_SIZE, $maxLength - $bytesRead);
if ($bufferSize == 0) {
break;
}
}
}
return false;
}

public function getBytes($length, $offset = null, $seekMethod = null) {
$this->seek($offset, $seekMethod);
$read = $this->read($length);
return $read;
}

public function bytesAre($string, $offset = null, $seekMethod = null) {
return ($this->getBytes(strlen($string), $offset) == $string);
}
}

Usage:

$info = getMicrosoftOfficeMimeInfo('hi.docx');
/*
Array
(
[type] => Microsoft Word 2007+
[mime] => application/vnd.openxmlformats-officedocument.wordprocessingml.document
[extension] => docx
)
*/

$info = getMicrosoftOfficeMimeInfo('hi.xlsx');
/*
Array
(
[type] => Microsoft Excel 2007+
[mime] => application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
[extension] => xlsx
)
*/

$info = getMicrosoftOfficeMimeInfo('hi.pptx');
/*
Array
(
[type] => Microsoft PowerPoint 2007+
[mime] => application/vnd.openxmlformats-officedocument.presentationml.presentation
[extension] => pptx
)
*/

$info = getMicrosoftOfficeMimeInfo('hi.zip');
// bool(false)

How do I detect MIME type via a file handle in PHP?

Instead of passing a file handle or a string, pass an SplFileObject. Using this, you get OO access to the file without directly calling file system functions. Functions that require a pathname can still by used by calling ->getRealPath() on the object.

$finfo     = new finfo(FILEINFO_MIME_TYPE); 
$mime_type = $finfo->file( $fileObject->getRealPath() );

Detect MIME Type of file extracted from Database

You can get mime type using finfo_open and finfo_buffer. In this example i read content of a image from google and get its mimetype:

<?php

$Resource = finfo_open(FILEINFO_MIME);
$Info = finfo_buffer($Resource, file_get_contents('https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png')); // Returns: image/png; charset=binary

list($Mime, $Other) = explode(";", $Info);

echo $Mime; // image/png


Related Topics



Leave a reply



Submit