我正在编写一个脚本来处理来自Web应用程序的文件上传.我对可以上传到我的应用程序的文件大小有一个限制(存储空间限制).我正在尝试放入一些验证代码,以确保用户实际上传了一个文件,以便我可以向他们显示一个很好的错误消息.但是,如果用户上传的文件太大,我也希望能够向用户显示错误消息.我可以使用Javascript,但我也想要一个PHP检查以防他们没有启用Javascript.
我已将PHP.ini中的POST_MAX_SIZE var设置为最大文件上载大小,但这会产生意外问题.如果有人尝试上传大于POST_MAX_SIZE的文件,则二进制数据将以最大大小截断,而$ _FILES数组不包含该文件的条目.这与用户根本不提交文件时会发生的行为相同.
这使得很难说出为什么$ _FILES数组不包含文件,即它是否曾经上传过,或者它是否太大而无法完全发送.
有没有办法区分这两种情况?换句话说,有没有办法判断是否为文件发送了POST数据,但是在整个文件发送之前是否过早地被截断了?
看起来很奇怪,这是有意的行为,因为POST_MAX_SIZE是低级别的最终故障保护,并且为了保护您并防止DOS攻击,服务器无法做任何事情,只有在意识到流中,它接收到的数据超出了它可以安全处理的范围。如果您知道需要一次接收比此更多的数据,则可以提高此值(但是请确保您的服务器可以处理将要承受的增加的负载),但我建议您考虑采用其他方法来处理用例,达到POST_MAX_SIZE的标准对我来说可能是比一个大型HTTP POST更为强大的解决方案,例如将其拆分为多个AJAX调用。
与POST_MAX_SIZE分开的是UPLOAD_MAX_SIZE,它是单个文件限制的php.ini设置,这是我最初假设的内容。它会限制任何一个上传文件的大小,如果文件超过此值,它将设置$_FILES['file']['error']为1。一般来说,您希望这样设置站点:
<form>MAX_FILE_SIZE应设置为你真正想要接受这种形式的最大值。尽管任何试图利用您的网站的用户都可以解决此问题,但对于实际使用您的网站的用户来说,这很好,因为浏览器可以(实际上)可以防止他们浪费带宽尝试上载它。该值应始终小于服务器端设置。$_FILES阵列。该文件应该大于您要在整个站点中实际接受的最大文件。对于您如何分辨的特定问题,我链接到POST_MAX_SIZE上的PHP文档,建议在表单中设置一个get变量,即
<form action="edit.php?processed=1">
Run Code Online (Sandbox Code Playgroud)
但是,就像我上面说的那样,如果您遇到此问题,则可能需要探索其他上传方法。
像这样的东西:
if ($_SERVER['CONTENT_LENGTH'] && !$_FILES && !$_POST) {
// upload failed
}
Run Code Online (Sandbox Code Playgroud)
未经测试,因此请使用各种方案来查看哪种组合有效.不确定它是否适用于同时进行多个文件上传.
您可能需要检查$_SERVER['CONTENT_LENGTH']并将其与处理多个上载时收到的文件总数进行比较.