如何用php找到文件的mime-type?

时间:2021-01-03 21:22:17

Ok, so I have an index.php file which has to process many different file types. how do I guess the filetype based on the REQUEST_URI.

好的,所以我有一个index.php文件,它必须处理许多不同的文件类型。我如何根据REQUEST_URI猜测文件类型。

If I request http://site/image.jpg, and all requests redirect through index.php, which looks like this

如果我请求http://site/image.jpg,并且所有请求都通过index.php重定向,这看起来像这样

<?php
   include('/www/site'.$_SERVER['REQUEST_URI']);
?>

How would I make that work correctly?

我该怎么做才能正常工作?

Should I test based on the extension of the file requested, or is there a way to get the filetype?

我应该根据所请求文件的扩展名进行测试,还是有办法获取文件类型?

13 个解决方案

#1


49  

If you are sure you're only ever working with images, you can check out the getimagesize() exif_imagetype() PHP function, which attempts to return the image mime-type.

如果您确定只使用过图像,可以查看getimagesize()exif_imagetype()PHP函数,该函数会尝试返回图像mime-type。

If you don't mind external dependencies, you can also check out the excellent getID3 library which can determine the mime-type of many different file types.

如果您不介意外部依赖项,您还可以查看优秀的getID3库,它可以确定许多不同文件类型的mime类型。

Lastly, you can check out the mime_content_type() function - but it has been deprecated for the Fileinfo PECL extension.

最后,您可以查看mime_content_type()函数 - 但不推荐使用Fileinfo PECL扩展。

#2


22  

mime_content_type() is deprecated, so you won't be able to count on it working in the future. There is a "fileinfo" PECL extension, but I haven't heard good things about it.

不推荐使用mime_content_type(),因此您将来无法依靠它。有一个“fileinfo”PECL扩展,但我没有听到有关它的好消息。

If you are running on a *nix server, you can do the following, which has worked fine for me:

如果您在* nix服务器上运行,则可以执行以下操作,这对我来说很好:

$file = escapeshellarg( $filename );
$mime = shell_exec("file -bi " . $file);
$filename should probably include the absolute path.

#3


17  

function get_mime($file) {
  if (function_exists("finfo_file")) {
    $finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
    $mime = finfo_file($finfo, $file);
    finfo_close($finfo);
    return $mime;
  } else if (function_exists("mime_content_type")) {
    return mime_content_type($file);
  } else if (!stristr(ini_get("disable_functions"), "shell_exec")) {
    // http://*.com/a/134930/1593459
    $file = escapeshellarg($file);
    $mime = shell_exec("file -bi " . $file);
    return $mime;
  } else {
    return false;
  }
}

For me, nothing of this does work - mime_content_type is deprecated, finfo is not installed, and shell_exec is not allowed.

对我来说,这没有任何作用 - 不推荐使用mime_content_type,未安装finfo,并且不允许使用shell_exec。

#4


10  

I actually got fed up by the lack of standard MIME sniffing methods in PHP. Install fileinfo... Use deprecated functions... Oh these work, but only for images! I got fed up of it, so I did some research and found the WHATWG Mimesniffing spec - I believe this is still a draft spec though.

我实际上厌倦了PHP中缺乏标准的MIME嗅探方法。安装fileinfo ...使用已弃用的功能......哦,这些工作,但仅适用于图像!我厌倦了它,所以我做了一些研究,发现了WHATWG Mimesniffing规范 - 我相信这仍然是草案规范。

Anyway, using this specification, I was able to implement a mimesniffer in PHP. Performance is not an issue. In fact on my humble machine, I was able to open and sniff thousands of files before PHP timed out.

无论如何,使用这个规范,我能够在PHP中实现一个mimesniffer。性能不是问题。事实上,在我不起眼的机器上,我能够在PHP超时之前打开并嗅探数千个文件。

Here is the MimeReader class.

这是MimeReader类。

require_once("MimeReader.php");

$mime = new MimeReader(<YOUR FILE PATH>);
$mime_type_string = $mime->getType();     // "image/jpeg" etc.

#5


8  

If you are working with Images only and you need mime type (e.g. for headers), then this is the fastest and most direct answer:

如果您只使用图像并且您需要mime类型(例如标题),那么这是最快且最直接的答案:

$file = 'path/to/image.jpg';
$image_mime = image_type_to_mime_type(exif_imagetype($file));

It will output true image mime type even if you rename your image file

即使重命名图像文件,它也会输出真实的图像mime类型

#6


1  

According to the php manual, the finfo-file function is best way to do this. However, you will need to install the FileInfo PECL extension.

根据php手册,finfo-file函数是执行此操作的最佳方法。但是,您需要安装FileInfo PECL扩展。

If the extension is not an option, you can use the outdated mime_content_type function.

如果扩展名不是选项,则可以使用过时的mime_content_type函数。

#7


1  

mime_content_type() appears to be the way to go, notwithstanding the above comments saying it is deprecated. It is not -- or at least this incarnation of mime_content_type() is not deprecated, according to http://php.net/manual/en/function.mime-content-type.php. It is part of the FileInfo extension, but the PHP documentation now tells us it is enabled by default as of PHP 5.3.0.

mime_content_type()似乎是要走的路,尽管上面的评论说它已被弃用。根据http://php.net/manual/en/function.mime-content-type.php,它不是 - 或者至少这个mime_content_type()的化身不被弃用。它是FileInfo扩展的一部分,但PHP文档现在告诉我们它自PHP 5.3.0起默认启用。

#8


1  

You can use finfo to accomplish this as of PHP 5.3:

从PHP 5.3开始,您可以使用finfo来完成此任务:

<?php
$info = new finfo(FILEINFO_MIME_TYPE);
echo $info->file('myImage.jpg');
// prints "image/jpeg"

The FILEINFO_MIME_TYPE flag is optional; without it you get a more verbose string for some files; (apparently some image types will return size and colour depth information). Using the FILEINFO_MIME flag returns the mime-type and encoding if available (e.g. image/png; charset=binary or text/x-php; charset=us-ascii). See this site for more info.

FILEINFO_MIME_TYPE标志是可选的;如果没有它,你会得到一些文件更详细的字符串; (显然一些图像类型将返回大小和颜色深度信息)。使用FILEINFO_MIME标志返回mime类型和编码(如果可用)(例如image / png; charset = binary或text / x-php; charset = us-ascii)。有关详细信息,请访问此站点。

#9


0  

I haven't used it, but there's a PECL extension for getting a file's mimetype. The official documentation for it is in the manual.

我没有使用它,但是有一个PECL扩展来获取文件的mimetype。它的官方文档在手册中。

Depending on your purposes, a file extension can be ok, but it's not incredibly reliable since it's so easily changed.

根据您的目的,文件扩展名可以正常,但它不是非常可靠,因为它很容易更改。

#10


0  

i got very good results using a user function from http://php.net/manual/de/function.mime-content-type.php @''john dot howard at prismmg dot com 26-Oct-2009 03:43''

我使用http://php.net/manual/de/function.mime-content-type.php @''john dot howard at prismmg dot com 26-Oct-2009 03:43'的用户函数获得了非常好的结果“

function get_mime_type($filename, $mimePath = '../etc') { ...

which doesnt use finfo, exec or deprecated function

哪个不使用finfo,exec或弃用的函数

works well also with remote ressources!

适用于远程资源!

#11


0  

if you're only dealing with images you can use the [getimagesize()][1] function which contains all sorts of info about the image, including the type.

如果您只处理图像,可以使用[getimagesize()] [1]函数,其中包含有关图像的各种信息,包括类型。

A more general approach would be to use the FileInfo extension from PECL. The PHP documentation for this extension can be found at: http://us.php.net/manual/en/ref.fileinfo.php

更通用的方法是使用PECL的FileInfo扩展。有关此扩展的PHP文档,请访问:http://us.php.net/manual/en/ref.fileinfo.php

Some people have serious complaints about that extension... so if you run into serious issues or cannot install the extension for some reason you might want to check out the deprecated function mime_content_type()

有些人对此扩展有严重的抱怨......所以如果您遇到严重问题或因某些原因无法安装扩展程序,您可能需要查看已弃用的函数mime_content_type()

#12


0  

If you run Linux and have the extension you could simply read the MIME type from /etc/mime.types by making a hash array. You can then store that in memory and simply call the MIME by array key :)

如果您运行Linux并具有扩展名,则可以通过创建哈希数组从/etc/mime.types中读取MIME类型。然后,您可以将其存储在内存中,只需通过数组键调用MIME :)

/**
 * Helper function to extract all mime types from the default Linux /etc/mime.types
 */
function get_mime_types() {
    $mime_types = array();
    if (
        file_exists('/etc/mime.types') &&
        ($fh = fopen('/etc/mime.types', 'r')) !== false
    ) {
        while (($line = fgets($fh)) !== false) {
            if (!trim($line) || substr($line, 0, 1) === '#') continue;
            $mime_type = preg_split('/\t+/', rtrim($line));
            if (
                is_array($mime_type) &&
                isset($mime_type[0]) && $mime_type[0] &&
                isset($mime_type[1]) && $mime_type[1]
            ) {
                foreach (explode(' ', $mime_type[1]) as $ext) {
                    $mime_types[$ext] = $mime_type[0];
                }
            }
        }
        fclose($fh);
    }
    return $mime_types;
}

#13


0  

The mime of any file on your server can be gotten with this

您可以使用此服务器获取服务器上任何文件的mime

<?php
function get_mime($file_path){
  $finfo = new finfo(FILEINFO_MIME_TYPE);
  $type  = $finfo->file(file_path);
}

$mime = get_mime('path/to/file.ext');

#1


49  

If you are sure you're only ever working with images, you can check out the getimagesize() exif_imagetype() PHP function, which attempts to return the image mime-type.

如果您确定只使用过图像,可以查看getimagesize()exif_imagetype()PHP函数,该函数会尝试返回图像mime-type。

If you don't mind external dependencies, you can also check out the excellent getID3 library which can determine the mime-type of many different file types.

如果您不介意外部依赖项,您还可以查看优秀的getID3库,它可以确定许多不同文件类型的mime类型。

Lastly, you can check out the mime_content_type() function - but it has been deprecated for the Fileinfo PECL extension.

最后,您可以查看mime_content_type()函数 - 但不推荐使用Fileinfo PECL扩展。

#2


22  

mime_content_type() is deprecated, so you won't be able to count on it working in the future. There is a "fileinfo" PECL extension, but I haven't heard good things about it.

不推荐使用mime_content_type(),因此您将来无法依靠它。有一个“fileinfo”PECL扩展,但我没有听到有关它的好消息。

If you are running on a *nix server, you can do the following, which has worked fine for me:

如果您在* nix服务器上运行,则可以执行以下操作,这对我来说很好:

$file = escapeshellarg( $filename );
$mime = shell_exec("file -bi " . $file);
$filename should probably include the absolute path.

#3


17  

function get_mime($file) {
  if (function_exists("finfo_file")) {
    $finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
    $mime = finfo_file($finfo, $file);
    finfo_close($finfo);
    return $mime;
  } else if (function_exists("mime_content_type")) {
    return mime_content_type($file);
  } else if (!stristr(ini_get("disable_functions"), "shell_exec")) {
    // http://*.com/a/134930/1593459
    $file = escapeshellarg($file);
    $mime = shell_exec("file -bi " . $file);
    return $mime;
  } else {
    return false;
  }
}

For me, nothing of this does work - mime_content_type is deprecated, finfo is not installed, and shell_exec is not allowed.

对我来说,这没有任何作用 - 不推荐使用mime_content_type,未安装finfo,并且不允许使用shell_exec。

#4


10  

I actually got fed up by the lack of standard MIME sniffing methods in PHP. Install fileinfo... Use deprecated functions... Oh these work, but only for images! I got fed up of it, so I did some research and found the WHATWG Mimesniffing spec - I believe this is still a draft spec though.

我实际上厌倦了PHP中缺乏标准的MIME嗅探方法。安装fileinfo ...使用已弃用的功能......哦,这些工作,但仅适用于图像!我厌倦了它,所以我做了一些研究,发现了WHATWG Mimesniffing规范 - 我相信这仍然是草案规范。

Anyway, using this specification, I was able to implement a mimesniffer in PHP. Performance is not an issue. In fact on my humble machine, I was able to open and sniff thousands of files before PHP timed out.

无论如何,使用这个规范,我能够在PHP中实现一个mimesniffer。性能不是问题。事实上,在我不起眼的机器上,我能够在PHP超时之前打开并嗅探数千个文件。

Here is the MimeReader class.

这是MimeReader类。

require_once("MimeReader.php");

$mime = new MimeReader(<YOUR FILE PATH>);
$mime_type_string = $mime->getType();     // "image/jpeg" etc.

#5


8  

If you are working with Images only and you need mime type (e.g. for headers), then this is the fastest and most direct answer:

如果您只使用图像并且您需要mime类型(例如标题),那么这是最快且最直接的答案:

$file = 'path/to/image.jpg';
$image_mime = image_type_to_mime_type(exif_imagetype($file));

It will output true image mime type even if you rename your image file

即使重命名图像文件,它也会输出真实的图像mime类型

#6


1  

According to the php manual, the finfo-file function is best way to do this. However, you will need to install the FileInfo PECL extension.

根据php手册,finfo-file函数是执行此操作的最佳方法。但是,您需要安装FileInfo PECL扩展。

If the extension is not an option, you can use the outdated mime_content_type function.

如果扩展名不是选项,则可以使用过时的mime_content_type函数。

#7


1  

mime_content_type() appears to be the way to go, notwithstanding the above comments saying it is deprecated. It is not -- or at least this incarnation of mime_content_type() is not deprecated, according to http://php.net/manual/en/function.mime-content-type.php. It is part of the FileInfo extension, but the PHP documentation now tells us it is enabled by default as of PHP 5.3.0.

mime_content_type()似乎是要走的路,尽管上面的评论说它已被弃用。根据http://php.net/manual/en/function.mime-content-type.php,它不是 - 或者至少这个mime_content_type()的化身不被弃用。它是FileInfo扩展的一部分,但PHP文档现在告诉我们它自PHP 5.3.0起默认启用。

#8


1  

You can use finfo to accomplish this as of PHP 5.3:

从PHP 5.3开始,您可以使用finfo来完成此任务:

<?php
$info = new finfo(FILEINFO_MIME_TYPE);
echo $info->file('myImage.jpg');
// prints "image/jpeg"

The FILEINFO_MIME_TYPE flag is optional; without it you get a more verbose string for some files; (apparently some image types will return size and colour depth information). Using the FILEINFO_MIME flag returns the mime-type and encoding if available (e.g. image/png; charset=binary or text/x-php; charset=us-ascii). See this site for more info.

FILEINFO_MIME_TYPE标志是可选的;如果没有它,你会得到一些文件更详细的字符串; (显然一些图像类型将返回大小和颜色深度信息)。使用FILEINFO_MIME标志返回mime类型和编码(如果可用)(例如image / png; charset = binary或text / x-php; charset = us-ascii)。有关详细信息,请访问此站点。

#9


0  

I haven't used it, but there's a PECL extension for getting a file's mimetype. The official documentation for it is in the manual.

我没有使用它,但是有一个PECL扩展来获取文件的mimetype。它的官方文档在手册中。

Depending on your purposes, a file extension can be ok, but it's not incredibly reliable since it's so easily changed.

根据您的目的,文件扩展名可以正常,但它不是非常可靠,因为它很容易更改。

#10


0  

i got very good results using a user function from http://php.net/manual/de/function.mime-content-type.php @''john dot howard at prismmg dot com 26-Oct-2009 03:43''

我使用http://php.net/manual/de/function.mime-content-type.php @''john dot howard at prismmg dot com 26-Oct-2009 03:43'的用户函数获得了非常好的结果“

function get_mime_type($filename, $mimePath = '../etc') { ...

which doesnt use finfo, exec or deprecated function

哪个不使用finfo,exec或弃用的函数

works well also with remote ressources!

适用于远程资源!

#11


0  

if you're only dealing with images you can use the [getimagesize()][1] function which contains all sorts of info about the image, including the type.

如果您只处理图像,可以使用[getimagesize()] [1]函数,其中包含有关图像的各种信息,包括类型。

A more general approach would be to use the FileInfo extension from PECL. The PHP documentation for this extension can be found at: http://us.php.net/manual/en/ref.fileinfo.php

更通用的方法是使用PECL的FileInfo扩展。有关此扩展的PHP文档,请访问:http://us.php.net/manual/en/ref.fileinfo.php

Some people have serious complaints about that extension... so if you run into serious issues or cannot install the extension for some reason you might want to check out the deprecated function mime_content_type()

有些人对此扩展有严重的抱怨......所以如果您遇到严重问题或因某些原因无法安装扩展程序,您可能需要查看已弃用的函数mime_content_type()

#12


0  

If you run Linux and have the extension you could simply read the MIME type from /etc/mime.types by making a hash array. You can then store that in memory and simply call the MIME by array key :)

如果您运行Linux并具有扩展名,则可以通过创建哈希数组从/etc/mime.types中读取MIME类型。然后,您可以将其存储在内存中,只需通过数组键调用MIME :)

/**
 * Helper function to extract all mime types from the default Linux /etc/mime.types
 */
function get_mime_types() {
    $mime_types = array();
    if (
        file_exists('/etc/mime.types') &&
        ($fh = fopen('/etc/mime.types', 'r')) !== false
    ) {
        while (($line = fgets($fh)) !== false) {
            if (!trim($line) || substr($line, 0, 1) === '#') continue;
            $mime_type = preg_split('/\t+/', rtrim($line));
            if (
                is_array($mime_type) &&
                isset($mime_type[0]) && $mime_type[0] &&
                isset($mime_type[1]) && $mime_type[1]
            ) {
                foreach (explode(' ', $mime_type[1]) as $ext) {
                    $mime_types[$ext] = $mime_type[0];
                }
            }
        }
        fclose($fh);
    }
    return $mime_types;
}

#13


0  

The mime of any file on your server can be gotten with this

您可以使用此服务器获取服务器上任何文件的mime

<?php
function get_mime($file_path){
  $finfo = new finfo(FILEINFO_MIME_TYPE);
  $type  = $finfo->file(file_path);
}

$mime = get_mime('path/to/file.ext');