【问题标题】:How do I find the mime-type of a file with php?如何使用 php 找到文件的 mime 类型?
【发布时间】:2015-09-20 17:08:34
【问题描述】:

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

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

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

我怎样才能让它正常工作?

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

【问题讨论】:

  • 你能改写你的问题吗?我希望你不要真的在你的网站上运行这样的代码。
  • 不,这当然不是它实际工作的方式。这只是理解这一点的最佳方式(所以我认为)。

标签: php filesystems http-headers content-type


【解决方案1】:

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

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

最后,您可以查看 mime_content_type() 函数 - 但它已被 Fileinfo PECL 扩展弃用。

【讨论】:

【解决方案2】:

mime_content_type() 已被弃用,因此您将无法指望它在未来工作。有一个“fileinfo”PECL 扩展,但我没有听说过它的好消息。

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

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

【讨论】:

  • 出于安全原因,file 命令可能被禁用(在共享主机上)。
  • 我没有听说过关于它的好消息。 - 如果我们能读懂你听到的内容就好了 ;)
  • 你说 mime_content_type 被弃用是基于什么?根据php.net/manual/en/function.mime-content-type.php 似乎没有被弃用。
【解决方案3】:
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://stackoverflow.com/a/134930/1593459
    $file = escapeshellarg($file);
    $mime = shell_exec("file -bi " . $file);
    return $mime;
  } else {
    return false;
  }
}

对我来说,这些都不起作用 - mime_content_type 已弃用,finfo 未安装,shell_exec 不允许使用。

【讨论】:

    【解决方案4】:

    我实际上厌倦了 PHP 中缺少 标准 MIME 嗅探方法。安装文件信息...使用不推荐使用的功能...哦,这些工作,但仅适用于图像!我厌倦了它,所以我做了一些研究并找到了WHATWG Mimesniffing spec - 我相信这仍然是一个草案规范。

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

    这里是MimeReader class

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

    【讨论】:

    • 听起来不错!现在是Living Standard — Last Updated 11 June 2013,所以不是草稿。你有没有设法使用这个上传/分享你的 PHP 代码?
    • 嗨特雷德。感谢您的更新,对于迟到的回复感到抱歉。你可以在我的迷你网站上找到我所有的项目(我知道,这并不多)。如果它流行起来,我可能会把它放在 github 上。一切都在项目之下。它已发布到公共领域,因此请随时清理代码(它需要它!)或以其他方式修改您认为合适的。 shane.social-library.org
    • 谢谢!我一定会看看这个! :]
    • 嗨 Syed Qarib,感谢您告诉我。按照你的建议,我已经更新了 github 的链接。
    • 这个类没有CSV类型。
    【解决方案5】:

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

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

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

    【讨论】:

      【解决方案6】:

      根据 php 手册,finfo-file 函数是最好的方法。但是,您需要安装FileInfo PECL 扩展。

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

      【讨论】:

      • 还有。自 PHP 5.3 起默认启用 Fileinfo 扩展
      • @Stann 不,不是! PHP Version 5.4.7 + Fatal error: Call to undefined function finfo_open() in C:\XAMPP\htdocs\....
      【解决方案7】:

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

      【讨论】:

        【解决方案8】:

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

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

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

        【讨论】:

          【解决方案9】:

          我没有使用它,但是有一个 PECL extension 用于获取文件的 mimetype。它的官方文档在the manual

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

          【讨论】:

            【解决方案10】:

            我使用来自的用户函数获得了非常好的结果 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') { ...
            

            不使用 finfo、exec 或不推荐使用的函数

            也适用于远程资源!

            【讨论】:

            • 这个函数在你写这个答案之前很久就被弃用了,所以提出这个解决方案是没有意义的。
            【解决方案11】:

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

            更通用的方法是使用 PECL 的 FileInfo 扩展。此扩展的 PHP 文档可在以下位置找到:http://us.php.net/manual/en/ref.fileinfo.php

            有些人对该扩展有严重的抱怨......因此,如果您遇到严重问题或由于某种原因无法安装扩展,您可能需要查看已弃用的功能 mime_content_type()

            【讨论】:

              【解决方案12】:

              如果您运行 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】:

                你的服务器上任何文件的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');
                

                【讨论】:

                  猜你喜欢
                  • 2010-09-07
                  • 2013-01-20
                  • 2018-09-13
                  • 2011-01-14
                  • 2014-03-21
                  • 2011-06-25
                  • 1970-01-01
                  相关资源
                  最近更新 更多