php $_files为空,PHP上传文件时$_FILES数组为空

本文探讨了使用Nginx+PHP环境下文件上传时遇到的特殊错误。当上传文件大小超过限制时,$_FILES数组可能会变成空。文章分析了php.ini和nginx.conf中关于文件上传大小的设置,并提供了解决方案。

今天在调试上传文件接口的时候发现了一个奇怪的错误,当上传的文件超过一定大小时$_FILES数组会变成空的。仔细研究了一下,发现这还是个挺冷门的错误。原因在于使用Nginx+PHP时,系统中一共有三个上传文件的大小限制:

php.ini 里的 upload_max_filesize

php.ini 里的 post_max_size

nginx.conf 里的 client_max_body_size

假设只上传一个文件,此时会出现三种不同的情况:

a) 文件大于1,小于2

b) 文件大于2,小于3

c) 文件大于3

其中a, c两种情况都很简单(假设该input的name="file"):

a情况中。超过php.ini中upload_max_filesize的值,可以在PHP中得到$_FILES['file']['error']==1。

c情况中,超过nginx.conf中的client_max_body_size,Nginx会返回413 Request Entity Too Large错误。

在b情况中,你能看到的就是$_FILES数组为空(即isset($_FILES['file']==FALSE)。

此时就出现了两种可能,一种是客户端的表单里没有file这个字段,另一种是有超限的附件使表单的大小超过了post_max_size。

如果客户端是网页,那还比较好办,在HTML表单里,文件类型的input即使没有选择文件,$_FILES[‘file’]也是在的,此时服务器端拿到的应该是$_FILES['file']['error']==4错误。因此当出现$_FILES为空时,就可以告诉用户上传文件过大了(前提是你确定表单没有问题,尤其是没有忘记加enctype=”multipart/form-data”属性)。

如果客户端是App的话,作为后端程序员难免有点拿不准客户端究竟传没传文件。这时还有一个办法,就是取Header中的Content-Length。也就PHP里的$_SERVER['CONTENT_LENGTH'],如果是没有传文件的话,纯文本的表单体积很小,通常在几十几百,而如果传了一个超过8M的文件,Content-Length会大于8388608。因此可以用ini_get('upload_max_filesize')取出upload_max_filesize的值,换算成字节数与Content-Length比较一下,来确定是哪种情况。

最后要说的是,尽管上面只讨论了上传单文件,但是这种错误更多见于一张表单上传多个文件,上传多个文件时,虽然每个文件的大小都小于upload_max_filesize,但是若多个文件加起来大于post_max_size,就会触发这个错误。debug时只看单个文件的大小,没有注意所有文件的总大小,bug就会时隐时现,非常让人头疼。不过话说回来,以现在公网的网速来讲,提交这么大的POST请求体验太差了,还是采取Ajax的方式逐个上传好一点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值