如何检查上传文件的类型是否为PDF

14

可能的重复问题:
如何在PHP中检查上传文件的文件类型?

我在网站上添加了上传功能,只允许PDF文件上传。如何检查上传的文件是PDF文件?就像getimagesize()可以验证图像文件一样。 是否有任何方法可以检查文件是PDF文件?我的代码如下:

$whitelist = array(".pdf");

foreach ($whitelist as $item) {
    if (preg_match("/$item\$/i", $_FILES['uploadfile']['name'])) {
        
    }
    else {
        redirect_to("index.php");
    }
}

$uploaddir = 'uploads/';

$uploadfile = mysql_prep($uploaddir . basename($_FILES['uploadfile']['name']));

if (move_uploaded_file($_FILES['uploadfile']['tmp_name'], $uploadfile)) {
    echo "succussfully uploaded";
}

我定义了redirect_tomysql_prep函数。但是可以使用头文件更改MIME类型。那么有没有办法检查文件是否为原始的pdf?


1
你为什么有一个空的 if?请使用适当的缩进来编写你的代码,否则会出现问题。 - PeeHaa
我只是想检查一下它是否匹配了吗? - StaticVariable
只需执行以下代码:if (!preg_match("/$item\$/i", $_FILES['uploadfile']['name'])) { redirect_to("index.php"); } - PeeHaa
这不是答案@PeeHaa..我已经做过了...如何像getimagesize()函数检查图像文件一样检查PDF条目 - StaticVariable
4
不是一个答案,而是一条评论。我告诉你如何改进你的代码 :) - PeeHaa
  1. 验证扩展名(pdf,doc,docx)*几乎无用
  2. 验证MIME
  3. 打开PDF文件,读取头部(第一行),并检查它是否包含以下字符串之一:%PDF-1.0,%PDF-1.1,%PDF-1.2,%PDF-1.3,%PDF-1.4
  4. 通过搜索多个“/ Page”来检查文件是否包含指定页面数的字符串
- Artur Kedzior
3个回答

20
您可以使用PHP的文件信息函数来检查文件的MIME类型。如果它返回类型为“application/pdf”,那么应该是一个PDF文件。
在PHP 5.3之前,您可以使用mime_content_type函数。但是自从PHP 5.3版本之后就添加了文件信息函数。

2
但如果我有一个 PHP 文件并写入(header: type="application/pdf")...那么它也会显示相同的内容。 - StaticVariable
那是真的,但那不太可能发生,这取决于这有多关键。 - Ben Evans
+1 这是唯一正确的答案。文件信息函数提供了一种获取文件真实 MIME 类型的方法。 - Sarfraz
3
需要注意的是(正如在SO的其他地方提到的那样),mime_content_type()函数并未被弃用,并且明确提到已包含在PHP7中。 - Alex Currie-Clark
我想补充一下,我发现了一个PDF文件,就我所知,它在所有方面都是正常的PDF文件,但是mime_content_type($filename)以及(new finfo(FILEINFO_MIME_TYPE))->file($filename)返回"application/octet-stream"。 - Clox
显示剩余3条评论

12

4
请注意,它已被弃用 - PeeHaa
2
@PeeHaa,你能更新一下你的回答吗?这个还没有被弃用。(请看链接。)也许它又复活了? - Jeremy L.
1
该更改已在52d6b9aa9b0000744b727e4a596539371f06fd11中被撤销。PHP的错误网站目前无法加载,但一旦恢复正常,您可以查看https://bugs.php.net/bug.php?id=71367以了解原因。@daprezjer - PeeHaa

11

通过打开文件并读取前几个字节的数据,查找PDF魔数。大多数文件都有特定的格式,而PDF文件以%PDF开头。

您可以检查文件的前5个字符,如果它们等于“%PDF-”,那么很可能是真正的PDF文件(但这并不能完全证明它是PDF文件,因为任何文件都可以以这5个字符开头)。在正确的PDF文件中,下4个字符包含版本号(即1.2)。


1
那是一个非常昂贵的解决方案!:D - HBv6
1
这不就是 MIME 类型检查所做的事情吗,只不过更便宜一些吗? - Frog
2
好的,这基本上就是 MIME 类型检查可能已经在做的事情。但是,如果您确实想更加确定它是有效的 PDF 文件(并且您不介意额外的处理时间),您可以扫描文件以查找其他预期结构,例如文件末尾的 PDF“%%EOF”标记。(假设这比 MIME 检查所做的更多) - Mike
这是一个非常不安全的解决方案,如果我试图打破这种保护,我会用我想要的字节替换前几个字节。非常容易做到。 - sf_admin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接