在 PHP 中检查“魔术字节”或 Mime 类型?

Posted

技术标签:

【中文标题】在 PHP 中检查“魔术字节”或 Mime 类型?【英文标题】:Checking "Magic Bytes" or Mime Types in PHP? 【发布时间】:2013-08-01 19:01:56 【问题描述】:

所以,我目前使用了几种不同的方法来检查 MIME 类型。用户使用表单上传文件,我获取 mime 类型,如果是 application/zip,我允许,如果是其他,我拒绝。问题是某些东西(我假设的浏览器)正在将 mime 类型更改为“application/octet-stream”

我想知道如何在表单上传时验证文件是 .zip。

代码:

  $name = strtolower(end(explode('.', $filename))); 
    $accepted_types = array('application/zip', 'application/x-zip-compressed',   'multipart/x-zip', 'application/x-compressed'); 

  foreach($accepted_types as $good_type)  
        if($good_type == $type)    
            $okay = true;  
            break;
         else 
            $okay = false;
        
  

【问题讨论】:

How do I find the mime-type of a file with php? 的可能重复项 不应该在表单发布中将文件内容类型更改为应用程序八位字节流。你能展示一下你是如何处理上传的吗 你也可以in_array($type, $accepted_types);你不需要循环。 这不是回答问题只有一个提示:您可以使用此代码$name=strtolower(pathinfo($filename,PATHINFO_EXTENSION)); 来获取扩展文件而不是$name = strtolower(end(explode('.', $filename))); 【参考方案1】:

使用mime-content-type。

$type = mime_content_type($filename);

【讨论】:

【参考方案2】:

FWIW,您可以使用 bin2hex 获取魔术字节。根据*** (https://en.m.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files),zip 的前 2 个十六进制字节 50 4B

$zip=file_get_contents("somefile.zip");

echo strtoupper (substr(bin2hex($zip),0,2)); //504B

【讨论】:

将整个 zip 文件读入内存,只是为了验证魔术字节,是一种浪费。另外,4 个字符,而不是 2 个。$F=fopen("somefile.zip","r");$magic=fread($F,2);fclose($F);echo strtoupper(substr(bin2hex($magic),0,4)); //504B

以上是关于在 PHP 中检查“魔术字节”或 Mime 类型?的主要内容,如果未能解决你的问题,请参考以下文章

上传文件中的 Mime 类型错误

检查文件 mime 类型是不是与 php 中的扩展名匹配

在 DRUPAL 中验证 PDF 文件上传中的 MIME 类型

检查浏览器是不是支持特定的 MIME 类型?

拒绝从 'file_name.php' 执行脚本,因为它的 MIME 类型 ('text/html') 不可执行,并且启用了严格的 MIME 类型检查

在没有 MIME 或扩展名的 PHP 中确定文件类型