PHP允许zip mimetypes

时间:2012-05-11 20:33:53

标签: php mime-types

我知道(从这个问题的答案:.rar, .zip files MIME Type),大多数人都将PHP中的zip文件检查为application/zipapplication/octet-stream,但我对此有几个问题:

  • 检查application/octet-stream是否安全(假设application/octet-stream可用于描述比zip更多的文件类型!)。我知道我也可以通过其他方式检查文件,但我认为我应该尽量保持一切尽可能简单
  • 我试图检查尽可能多的不同实际拉链类型;但是,有一些会产生一些意想不到的结果。我找到了mime-type为application/x-external-editor的1,但PHP在处理它时遇到了问题(尽管我得到的唯一错误是Warning: ZipArchive::close() [ziparchive.close]: Invalid or unitialized Zip object) - 这是否记录在任何地方?是否有PHP可以处理的实际x- mimetypes列表?

修改

回答以下问题:

  • 我正在使用$_FILES['fileatt']['type']检查mime类型,但使用mime_content_type()会得到相同的结果。不同的zip文件似乎是以下任何一种:'application/zip''application/x-compressed''application/x-zip-compressed''application/x-compressed''multipart/x-zip'。当mime类型被检测为application/x-external-editor时,我不明白为什么会出现错误。
  • 我安装了zip扩展程序,并在上传时从zip文件中提取所有文件。我没想过要检查错误。

我还发现了另一件我不太明白的事情:当我将以下代码用于PHP读取为application/x-external-editor的文件时:

if($zip->open($_FILES[fileatt]['tmp_name'])===TRUE)
{
    echo "success";
} else {
    echo "error";
} 

打印“错误”,但检查文件类型为

$res = $zip->open($_FILES[fileatt]['tmp_name']);
if($res)
{
    echo "success";
} else {
    echo "error";
} 

打印“成功”;在这段代码中,我假设布尔值实际上是使用==,而不是===,但为什么这会产生影响呢?

错误:

$res = $zip->open($_FILES[fileatt]['tmp_name']);
if($res===TRUE)
{
    echo "success";
} else {
    echo $res;
} 

打印19 - 19指的是哪个错误(http://uk3.php.net/manual/en/ziparchive.open.php)?!

1 个答案:

答案 0 :(得分:2)

永远不要相信mime类型,这很容易被客户端欺骗。如果他们愿意,他们可以提交一个exe并给它一个mime类型text/plain

所有zip文件都以标准本地文件头签名(0x04034b50)开头,因此您可以检查文件的前4个字节是否与zip签名字节匹配。有关详细信息,请参阅PKZIP Appnote

如果你启用了zip extension,你可以更进一步,尝试打开并阅读zip,以确保它是一个完全有效的zip文件。

这样的事情效果很好:

$zip = zip_open('/path/to/file.zip');
if (is_int($zip)) {
    echo "Error $zip encountered reading the file, is it a valid zip?";
} else {
    echo "Thanks for uploading a valid zip file!";
}
如果成功打开,

zip_open将返回一个资源,否则返回一个整数,表示读取该文件时发生的错误。

编辑:详细说明您的一些问题:

关于application/octet-stream:正如您所说,这是一种非常通用的类型。这只是意味着任何包含8位数据的文件,基本上都是一切。 application/zip是事实上的标准mime类型,但是一些客户端将使用您发现的其他值。另外,鉴于客户端可以轻松欺骗任何文件类型以使用application/zip,我不会依赖$_FILES['fileatt']['type'],因为它可以是任何内容。

AFIK,mime_content_type()只是查看文件扩展名并将其从系统上的mime.types文件映射到mime类型,或者内置到PHP中。如果有人在.zip文件上加了exe个扩展名,它仍会注册为application/zip。我相信某些扩展可能会检查文件头。

如果文件成功打开,

Zip::open()将返回TRUE,或者返回整数错误代码。因此,==将对错误给出误报,因为任何非零整数将使用==求值为true,因为它会将非零整数转换为TRUE。如果您要检查Zip::open的回复,则应始终使用$res === true来检查是否成功。您可以在页面底部的注释中找到错误代码here的含义。

结论:由于你说你已经解压缩了zip,因此根据mime类型进行验证可能不那么麻烦,但是更容易尝试打开文件并根据返回值进行操作值open。如果它返回true,你可以认为该文件是一个有效的zip文件(当然可能会在文件后面出现错误,但它们至少上传了类似zip文件的内容)。

希望能帮到你。