本文依照ci框架下的php上传类为例(应该通用的,各框架类大同小异)
首先,上传失败的原因分析
1、php.ini是否开启了上传功能,以及上传的大小限制
打开php.ini,首先找到
file_uploads = on ;是否允许通过HTTP上传文件的开关。默认为ON即是开
upload_tmp_dir ;文件上传至服务器上存储临时文件的地方,如果没指定就会用系统默认的临时文件夹
upload_max_filesize = 8m ;望文生意,即允许上传文件大小的最大值。默认为2M
post_max_size = 8m ;指通过表单POST给PHP的所能接收的最大值,包括表单里的所有值。默认为8M
一般地,设置好上述四个参数后,上传<=8M的文件是不成问题,在网络正常的情况下。
但如果要上传>8M的大体积文件,只设置上述四项还一定能行的通。
进一步配置以下的参数
max_execution_time = 600 ;每个PHP页面运行的最大时间值(秒),默认30秒
max_input_time = 600 ;每个PHP页面接收数据所需的最大时间,默认60秒
memory_limit = 8m ;每个PHP页面所吃掉的最大内存,默认8M
把上述参数修改后,在网络所允许的正常情况下,就可以上传大体积文件了
max_execution_time = 600
max_input_time = 600
memory_limit = 32m
file_uploads = on
upload_tmp_dir = /tmp
upload_max_filesize = 32m
post_max_size = 32m
2、服务器是否允许大文件上传及最大上传限制,以nginx为例,打开nginx.conf加入
client_max_body_size 1000m;
3、确定是否指定上传类型
然后,确定以上没有问题,那么就跟本文错误类型类似,个人感觉是被国内外浏览器的一些差异和文件类型的差异坑了。
首先看下框架附带的上传类,排查了下,问题出处,如图:
OK找到了出错的方法出,基本肯定是因为这个方法的判定出了问题了,然后看下这个方法:
public function is_allowed_filetype($ignore_mime = FALSE)
{
if ($this->allowed_types === '*')
{
return TRUE;
}
if (empty($this->allowed_types) OR ! is_array($this->allowed_types))
{
$this->set_error('upload_no_file_types', 'debug');
return FALSE;
}
$ext = strtolower(ltrim($this->file_ext, '.'));
if ( ! in_array($ext, $this->allowed_types, TRUE))
{
return FALSE;
}
// Images get some additional checks
if (in_array($ext, array('gif', 'jpg', 'jpeg', 'jpe', 'png'), TRUE) && @getimagesize($this->file_temp) === FALSE)
{
return FALSE;
}
if ($ignore_mime === TRUE)
{
return TRUE;
}
if (isset($this->_mimes[$ext]))
{
return is_array($this->_mimes[$ext])
? in_array($this->file_type, $this->_mimes[$ext], TRUE)
: ($this->_mimes[$ext] === $this->file_type);
} //这里,排查了下发现这里判定出错,导致方法返回false
return FALSE;
}
ok,看以上方法,本次上传的是MP4文件,mime为‘video/mp4’,不是数组。
那么肯定 ‘$this->_mimes[$ext] === $this->file_type‘ 这里出了问题,简单就是文件mime与config设定不匹配。
有点纳闷,然后打印出来两个变量,看了下,果然 ,file_type 竟然是‘video/x-m4v’,貌似在哪见过 。。。。还是Google下
OK,你赢了,我是没想到还有这种操作。。。
问题解决了,就是不知道什么时候MP4文件里会继续融入x-m4a,x-flv这样的mime。。。