在 PHP 将文件上传到临时文件夹之前检查文件类型(FLV),方法是只读取文件的开头 3 个字节

Posted

技术标签:

【中文标题】在 PHP 将文件上传到临时文件夹之前检查文件类型(FLV),方法是只读取文件的开头 3 个字节【英文标题】:Check file type (FLV) before PHP upload file in temporary folder by reading only starting 3 bytes of file 【发布时间】:2013-06-24 19:14:54 【问题描述】:

FLV 文件的前 3 个字节是签名“FLV”。现在我的问题:

php中是否有可能处理文件上传,以便我们可以挂钩到上传文件的输入流并检查前3个字节?

场景是我不想上传完整的文件(在临时文件夹中)然后检查文件是否为 FLV,我只想读取上传流的前几个字节,如果不是“ FLV" 然后返回/退出。

文件需要通过基于 html 的表单上传。不能依赖 javascript、flash 上传器或任何客户端验证解决方法,即需要纯 PHP 的解决方案。

我已经知道 PHP 在完成将文件上传到临时文件夹并填充全局变量(即 $_POST $_GET $_FILES 等)之前不会将控制权交给我们的脚本。

这里还有一个类似的问题: How to upload a file byte by byte in php

但答案不满足我的要求/问题。

任何想法都非常感谢!

谢谢

【问题讨论】:

你能用:$file = fopen(..); if(fgets($file, 3) === "FLV").. fclose($file);吗? @DannyBeckett 请在此处阅读 fopen 手册:link。它不允许连接到客户端 PC 进行文件上传。它确实允许通过支持的协议打开服务器上的文件或文件,但都不符合我的要求 这就是为什么我问如果你可以使用它... 【参考方案1】:

首先,在您的php.ini 中设置session.upload_progress.enabled

然后,使用session.upload_progress 跟踪已上传的字节数。达到最低阈值后,检查正在上传的临时文件,它将位于$_SESSION[unique_key]['files'][0]['tmp_name']。如果文件不匹配,将$_SESSION[unique_key]["cancel_upload"]设置为TRUE,文件将被拒绝。

获取unique_key

ini_get("session.upload_progress.prefix") . $_POST[ini_get("session.upload_progress.name")];

如果上述方法不起作用(我还没有测试过),那么您唯一的办法就是为 PHP 创建自己的自定义处理程序,或者作为 Apache 模块(或者更好的是,作为自定义 CGI 应用程序)。在那里你可以进行过滤。

【讨论】:

+1 给你。这是我很久以来的一个问题。非常感谢。 @Burhan Khalid,感谢您的回答。我之前也遇到过这个问题,但是有两个问题,1:它只适用于 php 5.4 或更高版本,2nd:为了跟踪进度,我必须通过 ajax 生成另一个对服务器的请求,即必须使用客户端技术,我在我的问题中提到的不是一个选项 这与客户端无关,您也没有提到任何特定的PHP版本要求。 5.4 已经是 old 稳定版(当前稳定版是 5.5)。 @BurhanKhalid 好的,我当然可以应付版本,但是我如何在不向服务器生成第二个请求的情况下跟踪进度,因为我上传文件的脚本将无法访问,除非文件已完全上传。我必须向服务器生成另一个请求以运行您提供的代码(以跟踪进度),这只能通过一些客户端解决方法来完成,或者还有其他任何事情,请告诉我 您需要使用 Apache 模块运行 PHP,而不是在 FastCGI 下运行(否则,只有在文件完全上传后才能运行)。您还需要禁用 APC 并确保您没有设置自定义会话 ID;如果这些都不可能,您还有两个选择 - 使用客户端轮询解决方案,或者为 PHP 创建自己的自定义处理程序。【参考方案2】:

@burhan-khalid 在上面提供了更新和正确的答案。

简短的回答是与您的限制。

在将文件上传到服务器之前,您无法使用 PHP 访问该文件。上传后您可以阅读它,但之前不能阅读,至少在没有某种类型的客户端软件允许您将其流式传输到 PHP 而不是正常的表单提交时。

【讨论】:

原生 php 函数是不可能的,我已经知道了,但是 PHP 本身处理文件上传到临时文件夹,所以应该有一些处理程序/函数这样做,我需要了解它们和如果有可能吸引他们 我知道我的答案可能让您不满意,但对正确答案投反对票并不是很好。我告诉你的是正确的。根本没有办法使用标准的 HTTP POST 和 PHP。如果您想创建一个 Flash 客户端,它将通过管道逐字节发送到 PHP 文件,您可以这样做,但您的约束不允许这样做。 首先我没有投反对票,就好像我必须,我会,在你发帖的第一天。其次,你的答案不正确。正如@BurhanKhalid 提到的那样,有一种方法可以跟踪文件上传进度,不是绝对按照要求,但至少有一个带有 HTTP POST 和 PHP 的解决方案。 抱歉,我的立场已得到纠正。当我注意到我的投票被否决时,我没有看到@BurhanKhalid 的回答。仍在学习系统。

以上是关于在 PHP 将文件上传到临时文件夹之前检查文件类型(FLV),方法是只读取文件的开头 3 个字节的主要内容,如果未能解决你的问题,请参考以下文章

PHP:如何正确检查文件的 MIME 类型?

PHP文件上传

PHP图片上传安全检查清单

检查上传的文件是不是在 php 中属于不安全的文件类型

上传文件中的 Mime 类型错误

文件下载与上传