11

可能重复:
如何检测用户是否上传了大于 post_max_size 的文件?

我正在编写一个脚本来处理来自 Web 应用程序的文件上传。我对可以上传到我的应用程序的文件大小设置了限制(存储空间限制)。我目前正在尝试放入一些验证代码,以确保用户实际上传了文件,以便我可以向他们显示一个很好的错误消息。但是,如果用户上传了太大的文件,我也希望能够向用户显示错误消息。我可以为此使用 Javascript,但我也想要一个 PHP 检查,以防他们没有启用 Javascript。

我已将 PHP.ini 中的 POST_MAX_SIZE 变量设置为最大文件上传大小,但这产生了一个意外问题。如果有人尝试上传大于 POST_MAX_SIZE 的文件,二进制数据只会在最大大小处被截断,并且 $_FILES 数组不包含该文件的条目。如果用户根本没有提交文件,这与会发生的行为相同。

这使得很难判断为什么 $_FILES 数组不包含文件,即它是否从未上传过,或者它是否太大而无法完全发送。

有没有办法区分这两种情况?换句话说,有没有办法判断是否为文件发送了 POST 数据,但在发送整个文件之前被提前截断了?

4

2 回答 2

7

看起来很奇怪,这是故意行为,因为 POST_MAX_SIZE 是一种低级的终极故障保护,为了保护您并防止 DOS 攻击,服务器除了在中途实现时丢弃所有 POST 数据之外别无他法,它接收的数据多于它可以安全处理的数据。如果您知道您需要一次接收比这更多的数据,您可以提高此值(但请确保您的服务器可以处理这将增加的负载),但我建议您研究处理您的用例的其他方法,遇到 POST_MAX_SIZE 向我表明,可能存在比一个大型 HTTP POST 更强大的解决方案,例如将其拆分为多个 AJAX 调用。

与 POST_MAX_SIZE 不同的是 UPLOAD_MAX_SIZE ,它是单个文件限制的 php.ini 设置,我假设您最初正在谈论这个设置。它限制任何一个上传文件的大小,如果文件超过这个值,它将设置$_FILES['file']['error']1. 一般来说,您希望您的网站设置如下:

  • MAX_FILE_SIZE<form>应设置为您实际希望为此表单接受的最大值。虽然任何试图利用您的网站的用户都可以绕过这个问题,但对于实际使用您的网站的用户来说这很好,因为浏览器将(实际上可以)阻止他们浪费带宽尝试上传它。这应该始终小于您的服务器端设置。
  • UPLOAD_MAX_FILESIZE是服务器将接受的最大大小,丢弃任何更大的内容并将错误报告给$_FILES阵列。这应该大于您希望在整个站点中实际接受的最大文件。
  • POST_MAX_SIZE是您的服务器愿意在单个 POST 请求中接受的最大数据量。这必须大于 UPLOAD_MAX_SIZE 才能使大型上传成功,并且必须大得多才能允许一次上传多个文件。我可能会建议 UPLOAD_MAX_FILESIZE * 4.1 的值 - 这将允许一次四个大文件,以及一些额外的数据。当然是 YMMV,而且您应该确保您的服务器能够正确处理您决定设置的任何值。

对于您如何判断的具体问题,我链接到的关于 POST_MAX_SIZE 的 PHP 文档建议在表单中设置一个 get 变量,即

<form action="edit.php?processed=1">

但是,就像我上面所说的,如果您遇到此问题,您可能需要探索其他上传方法。

于 2012-07-13T18:51:49.230 回答
6

像这样的东西:

if ($_SERVER['CONTENT_LENGTH'] && !$_FILES && !$_POST) {
  // upload failed
}

未经测试,因此请尝试各种场景以查看哪种组合有效。不确定它是否适用于同时上传多个文件。

如果处理多个上传,您可能需要检查$_SERVER['CONTENT_LENGTH']并将其与收到的文件总和进行比较。

于 2012-07-13T18:58:21.990 回答