- finfo::file
- Список параметров
- Возвращаемые значения
- Список изменений
- Примеры
- Смотрите также
- User Contributed Notes 13 notes
- mime_content_type
- Список параметров
- Возвращаемые значения
- Ошибки
- Примеры
- Смотрите также
- User Contributed Notes 21 notes
- Работа с MIME на PHP
- Определение MIME-типа загруженного файла
- Отправка файла через PHP
finfo::file
Функция используется для получения информации о файле.
Список параметров
Экземпляр finfo , возвращаемый функцией finfo_open() .
Название проверяемого файла.
Одна или несколько объединённых через бинарное ИЛИ констант Fileinfo.
Для описания contexts , смотрите Функции для работы с потоками.
Возвращаемые значения
Возвращает текстовое описание содержимого файла filename или false в случае возникновения ошибки.
Список изменений
Версия | Описание |
---|---|
8.1.0 | Параметр finfo теперь ожидает экземпляр finfo ; ранее ожидался ресурс (resource). |
8.0.0 | context теперь допускает значение null. |
Примеры
Пример #1 Пример использования finfo_file()
$finfo = finfo_open ( FILEINFO_MIME_TYPE ); // возвращает mime-тип
foreach ( glob ( «*» ) as $filename ) echo finfo_file ( $finfo , $filename ) . «\n» ;
>
finfo_close ( $finfo );
?>?php
Результатом выполнения данного примера будет что-то подобное:
text/html image/gif application/vnd.ms-excel
Смотрите также
User Contributed Notes 13 notes
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
>
The way HOWTO get MIME-type of remote file.
class MimeStreamWrapper
const WRAPPER_NAME = ‘mime’ ;
public $context ;
private static $isRegistered = false ;
private $callBackFunction ;
private $eof = false ;
private $fp ;
private $path ;
private $fileStat ;
private function getStat ()
if ( $fStat = fstat ( $this -> fp )) return $fStat ;
>
$size = 100 ;
if ( $headers = get_headers ( $this -> path , true )) $head = array_change_key_case ( $headers , CASE_LOWER );
$size = (int) $head [ ‘content-length’ ];
>
$blocks = ceil ( $size / 512 );
return array(
‘dev’ => 16777220 ,
‘ino’ => 15764 ,
‘mode’ => 33188 ,
‘nlink’ => 1 ,
‘uid’ => 10000 ,
‘gid’ => 80 ,
‘rdev’ => 0 ,
‘size’ => $size ,
‘atime’ => 0 ,
‘mtime’ => 0 ,
‘ctime’ => 0 ,
‘blksize’ => 4096 ,
‘blocks’ => $blocks ,
);
>
public function setPath ( $path )
$this -> path = $path ;
$this -> fp = fopen ( $this -> path , ‘rb’ ) or die( ‘Cannot open file: ‘ . $this -> path );
$this -> fileStat = $this -> getStat ();
>
public function read ( $count ) return fread ( $this -> fp , $count );
>
public function getStreamPath ()
return str_replace (array( ‘ftp://’ , ‘http://’ , ‘https://’ ), self :: WRAPPER_NAME . ‘://’ , $this -> path );
>
public function getContext ()
if (! self :: $isRegistered ) stream_wrapper_register ( self :: WRAPPER_NAME , get_class ());
self :: $isRegistered = true ;
>
return stream_context_create (
array(
self :: WRAPPER_NAME => array(
‘cb’ => array( $this , ‘read’ ),
‘fileStat’ => $this -> fileStat ,
)
)
);
>
public function stream_open ( $path , $mode , $options , & $opened_path )
if (! preg_match ( ‘/^r[bt]?$/’ , $mode ) || ! $this -> context ) return false ;
>
$opt = stream_context_get_options ( $this -> context );
if (! is_array ( $opt [ self :: WRAPPER_NAME ]) ||
!isset( $opt [ self :: WRAPPER_NAME ][ ‘cb’ ]) ||
! is_callable ( $opt [ self :: WRAPPER_NAME ][ ‘cb’ ])
) return false ;
>
$this -> callBackFunction = $opt [ self :: WRAPPER_NAME ][ ‘cb’ ];
$this -> fileStat = $opt [ self :: WRAPPER_NAME ][ ‘fileStat’ ];
return true ;
>
public function stream_read ( $count )
if ( $this -> eof || ! $count ) return » ;
>
if (( $s = call_user_func ( $this -> callBackFunction , $count )) == » ) $this -> eof = true ;
>
return $s ;
>
public function stream_eof ()
return $this -> eof ;
>
public function stream_stat ()
return $this -> fileStat ;
>
public function stream_cast ( $castAs )
$read = null ;
$write = null ;
$except = null ;
return @ stream_select ( $read , $write , $except , $castAs );
>
>
$path = ‘http://fc04.deviantart.net/fs71/f/2010/227/4/6/PNG_Test_by_Destron23.png’ ;
echo «File: » , $path , «\n» ;
$wrapper = new MimeStreamWrapper ();
$wrapper -> setPath ( $path );
$fInfo = new finfo ( FILEINFO_MIME );
echo «MIME-type: » , $fInfo -> file ( $wrapper -> getStreamPath (), FILEINFO_MIME_TYPE , $wrapper -> getContext ()), «\n» ;
?>
Just noting (because I ran into it!) that the current implementation of finfo_file has a known bug which causes PHP to allocate huge amounts of memory when certain strings are present in text files that it is examining.
Well, i have a great probleam with that, MS Office 2007 extensions (pptx, xlsx, docx) do not have a default Mime type, they have «application/zip» mime type, so, to fix that, i do one little function to verify the extension.
That function allow’s you to be safe of fake extensions hack.
$arrayZips = array( «application/zip» , «application/x-zip» , «application/x-zip-compressed» );
$arrayExtensions = array( «.pptx» , «.docx» , «.dotx» , «.xlsx» );
$original_extension = ( false === $pos = strrpos ( $file , ‘.’ )) ? » : substr ( $file , $pos );
$finfo = new finfo ( FILEINFO_MIME );
mime_content_type
Возвращает MIME-тип содержимого файла, используя для определения информацию из файла magic.mime .
Список параметров
Путь к проверяемому файлу.
Возвращаемые значения
Возвращает тип содержимого в формате MIME, например text/plain или application/octet-stream или false в случае возникновения ошибки.
Ошибки
В случае неудачного завершения работы генерируется ошибка уровня E_WARNING .
Примеры
Пример #1 Пример mime_content_type()
Результат выполнения данного примера:
Смотрите также
User Contributed Notes 21 notes
Fast generation of uptodate mime types:
echo
generateUpToDateMimeArray ( APACHE_MIME_TYPES_URL );
?>
Output:
$mime_types = array(
‘123’ => ‘application/vnd.lotus-1-2-3’,
‘3dml’ => ‘text/vnd.in3d.3dml’,
‘3g2’ => ‘video/3gpp2’,
‘3gp’ => ‘video/3gpp’,
‘7z’ => ‘application/x-7z-compressed’,
‘aab’ => ‘application/x-authorware-bin’,
‘aac’ => ‘audio/x-aac’,
‘aam’ => ‘application/x-authorware-map’,
‘aas’ => ‘application/x-authorware-seg’,
.
There is a composer package that will do this:
https://github.com/ralouphie/mimey
$mimes = new \ Mimey \ MimeTypes ;
// Convert extension to MIME type:
$mimes -> getMimeType ( ‘json’ ); // application/json
// Convert MIME type to extension:
$mimes -> getExtension ( ‘application/json’ ); // json
and string detection on text files may fail if you check a file encoded with signed UTF-8. The UTF-8 signature is a two bytes code (0xFF 0xFE) that prepends the file in order to force UTF-8 recognition (you may check it on an hexadecimal editor).
For me mime_content_type didn’t work in Linux before I added
to php.ini (remember to find the correct path to mime.magic)
using
function detectFileMimeType ( $filename = » )
$filename = escapeshellcmd ( $filename );
$command = «file -b —mime-type -m /usr/share/misc/magic < $filename >» ;
$mimeType = shell_exec ( $command );
return trim ( $mimeType );
>
?>
should work on most shared linux hosts without errors. It should also work on Windows hosts with msysgit installed.
Lukas V is IMO missing some point. The MIME type of a file may not be corresponding to the file suffix.
Imagine someone would obfuscate some PHP code in a .gif file, the file suffix would be ‘GIF’ but the MIME would be text/plain or even text/html.
Another example is files fetched via a distant server (wget / fopen / file / fsockopen. ). The server can issue an error, i.e. 404 Not Found, wich again is text/html, whatever you save the file to (download_archive.rar).
His provided function should begin by the test of the function existancy like :
function MIMEalternative($file)
if(function_exists(‘mime_content_type’))
return mime_content_type($file);
else
return ($file);
>
I see a lot of comments suggesting doing file extension sniffing (i.e. assuming .jpg files are JPEG images) when proper file-type sniffing functions are unavailable.
I want to point out that there is a much more accurate way.
If neither mime_content_type() nor Fileinfo is available to you and you are running *any* UNIX variant since the 70s, including Mac OS, OS X, Linux, etc. (and most web hosting is), just make a system call to ‘file(1)’.
Doing something like this:
echo system ( «file -bi »» );
?>
will output something like «text/html; charset=us-ascii». Some systems won’t add the charset bit, but strip it off just in case.
The ‘-bi’ bit is important. However, you can use a command like this:
echo system ( «file -b »» ); // without the ‘i’ after ‘-b’
?>
to output a human-readable string, like «HTML document text», which can sometimes be useful.
The only drawback is that your scripts will not work on Windows, but is this such a problem? Just about all web hosts use a UNIX.
It is a far better way than just examining the file extension.
Here’s a simple function to return MIME types, based on the Apache mime.types file. [The one in my previous submission, which has since been replaced by this one] only works properly if mime.types is formatted as Windows text. The updated version below corrects this problem. Thanks to Mike for pointing this out.
function get_mime_type ( $filename , $mimePath = ‘../etc’ ) <
$fileext = substr ( strrchr ( $filename , ‘.’ ), 1 );
if (empty( $fileext )) return ( false );
$regex = «/^([\w\+\-\.\/]+)\s+(\w+\s)*( $fileext \s)/i» ;
$lines = file ( » $mimePath /mime.types» );
foreach( $lines as $line ) <
if ( substr ( $line , 0 , 1 ) == ‘#’ ) continue; // skip comments
$line = rtrim ( $line ) . » » ;
if (! preg_match ( $regex , $line , $matches )) continue; // no match to the extension
return ( $matches [ 1 ]);
>
return ( false ); // no match at all
>
?>
Notes:
[1] Requires mime.types file distributed with Apache (normally found at ServerRoot/conf/mime.types). If you are using shared hosting, download the file with the Apache distro and then upload it to a directory on your web server that php has access to.
>> echo get_mime_type(‘myFile.xml’);
>> application/xml
>> echo get_mime_type(‘myPath/myFile.js’);
>> application/javascript
>> echo get_mime_type(‘myPresentation.ppt’);
>> application/vnd.ms-powerpoint
>> echo get_mime_type(‘http://mySite.com/myPage.php);
>> application/x-httpd-php
>> echo get_mime_type(‘myPicture.jpg’);
>> image/jpeg
>> echo get_mime_type(‘myMusic.mp3’);
>> audio/mpeg
and so on.
To create an associative array containing MIME types, use:
function get_mime_array ( $mimePath = ‘../etc’ )
<
$regex = «/([\w\+\-\.\/]+)\t+([\w\s]+)/i» ;
$lines = file ( » $mimePath /mime.types» , FILE_IGNORE_NEW_LINES );
foreach( $lines as $line ) <
if ( substr ( $line , 0 , 1 ) == ‘#’ ) continue; // skip comments
if (! preg_match ( $regex , $line , $matches )) continue; // skip mime types w/o any extensions
$mime = $matches [ 1 ];
$extensions = explode ( » » , $matches [ 2 ]);
foreach( $extensions as $ext ) $mimeArray [ trim ( $ext )] = $mime ;
>
return ( $mimeArray );
>
?>
Работа с MIME на PHP
«Internet Media Types» или «Медиа типы» — является стандартом RFC 6838, показывающий браузеру формат загружаемого файла. Почти все современные браузеры проверяют MIME-тип файла в качестве основного показателя определения расширения файла. MIME-типы используются при создании корпоративных сайтов и разработке сложных интернет-магазинов где нужно загружать или скачивать документы, прайсы, и другие файлы. MIME-тип состоит из двух частей разделённых косой линией «/», в нижнем регистре и без пробелов Также к медиа типу можно добавить дополнительный параметр для указания например кодировки: text/html; charset=utf-8
Определение MIME-типа загруженного файла
Для того чтобы узнать MIME уже загруженного файла в PHP существует функция mime_content_type().
Для получения MIME-типа изображения используется функция getimagesize():
При написании программных модулей по проверке файлов нельзя полагаться только на проверку MIME, т.к. его значение может быть не всегда правильным. Обычно нужно дополнительно проводить еще онду проверку по расширению, размеру изображения, а лучше для максимальной безопасности пересохранить файл в предполагаемом формате.
Отправка файла через PHP
В PHP, перед отправкой файлов через браузер на уровне клиента, необходимо формировать заголовок Content-Type:
Архив ZIP:
Определяем расширение файла изображения и выводим его с соответствующим заголовоком: