我知道(从这个问题的答案:.rar, .zip files MIME Type),大多数人都将PHP中的zip文件检查为application/zip
或application/octet-stream
,但我对此有几个问题:
application/octet-stream
是否安全(假设application/octet-stream
可用于描述比zip更多的文件类型!)。我知道我也可以通过其他方式检查文件,但我认为我应该尽量保持一切尽可能简单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
时,我不明白为什么会出现错误。我还发现了另一件我不太明白的事情:当我将以下代码用于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)?!
答案 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文件的内容)。
希望能帮到你。