检查上传到临时文件夹的PHP文件类型(FLV),只需读取文件开头3个字节即可。

15
FLV 文件的前三个字节是签名“FLV”。现在我的问题是:
在 PHP 中有没有可能处理文件上传,以便我们可以钩入上传文件的输入流并检查前三个字节?
场景是我不想完整地上传文件(到临时文件夹),然后再检查文件是否为 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); - Danny Beckett
2
@DannyBeckett 请在这里阅读 fopen 的手册:链接。它不允许连接到客户机以进行文件上传。它允许在服务器上打开文件或通过支持的协议打开文件,但这两种情况都无法满足我的要求。 - Umair Khan
这就是为什么我问你能否使用它的原因... - Danny Beckett
2个回答

9
首先,在您的php.ini中设置session.upload_progress.enabled
然后,使用session.upload_progress来跟踪上传了多少字节。一旦达到最小阈值,请检查正在上传的临时文件,它将位于$_SESSION[unique_key]['files'][0]['tmp_name']中。如果文件不匹配,则将$_SESSION[unique_key]["cancel_upload"]设置为TRUE,文件将被拒绝。
要获取unique_keyini_get("session.upload_progress.prefix") . $_POST[ini_get("session.upload_progress.name")]; 如果上述方法不起作用(我没有测试过),那么您唯一的选择就是创建自己的PHP自定义处理程序,作为Apache模块(或更好地作为自定义CGI应用程序)。在那里,您可以进行筛选。

+1 给你。这是我很久以来的一个问题。非常感谢。 - Sina R.
@Burhan Khalid,感谢您的回答。我之前也遇到过这个问题,但有两个问题:1:它只适用于PHP 5.4或更高版本,2:要跟踪进度,我必须通过ajax生成另一个请求发送到服务器,即必须使用客户端技术,而我在问题中提到这不是一个选项。 - Umair Khan
这与客户端无关,而且您没有提到任何特定的PHP版本要求。5.4已经是旧的稳定版本(当前稳定版本为5.5)。 - Burhan Khalid
@BurhanKhalid 好的,我可以应对版本问题,但是如果不生成第二个请求到服务器,我怎么能跟踪进度呢?因为上传文件的脚本在文件完全上传之前是无法访问的。我必须生成另一个请求到服务器来运行您提供的代码(以跟踪进度),这只能通过一些客户端解决方法来完成,或者还有其他方法,请告诉我。 - Umair Khan
你需要使用Apache模块来运行PHP,而不是使用FastCGI(否则,这仅在文件完全上传后才能工作)。你还需要禁用APC,并确保您没有设置自定义会话ID;如果这些都不可行,你还有两个选择 - 使用客户端轮询解决方案,或创建自己的PHP自定义处理程序。 - Burhan Khalid
我正在作为Apache模块运行PHP,没有APC。假设我有一个名为upload.php的文件,我正在上传文件(表单操作设置为upload.php)。现在根据您提供的代码来跟踪进度,我需要创建另一个脚本,比如说track.php,并且以常规间隔点击它来跟踪和取消上传(如果需要的话),对吗?那么我怎么能在这里排除AJAX呢? - Umair Khan

3

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

简短回答是不行(在你的限制下)。

在文件上传至服务器之前,你不能使用PHP访问该文件。上传后,您可以读取它,但在此之前,至少需要某种客户端软件才能将其流式传输到PHP,而不是正常的表单提交。


1
使用原生的PHP函数是不可能实现的,我已经知道了。但是PHP本身会将文件上传到临时文件夹中,因此应该有一些处理程序/函数来完成这个过程。我需要了解它们,并确定是否可以挂接它们。 - Umair Khan
我知道我的回答可能没有让您满意,但是对一个正确的回答进行负评并不好。我告诉您的是正确的。使用标准的HTTP POST和PHP根本没有办法。如果您想创建一个Flash客户端,通过管道逐字节发送到PHP文件中,那么可以实现,但这不符合您的限制条件。 - Marc Seiler
首先,我并没有对你的回答进行负评,因为如果我想这么做,那就会在你第一天发布问题时进行。其次,你的回答是不正确的。正如@BurhanKhalid所提到的,确实有一种跟踪文件上传进度的方法,虽然不完全符合要求,但至少有一个使用HTTP POST和PHP的解决方案。 - Umair Khan
抱歉,我改正了。当我注意到我的回答被踩的时候,我没有看到@BurhanKhalid的回答。我还在学习这个系统。 - Marc Seiler

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