发现问题

笔者在laravel5.1.*中使用图片上传时$request无法解析binary二进制图片,并报错mimeType: "application/octet-stream" -error: 6

查找问题

使用dd($request->all())调试具体错误信息如下:

array:1 [
  "image" => UploadedFile {#30
    -test: false
    -originalName: "1.jpg"
    -mimeType: "application/octet-stream"
    -size: 0
    -error: 6
  }
]

由此可见在Illuminate\Http\Request在解析binary就已经报错了

深入查看下有关Request包处理file代码,看到error状态码有以下几种情况:

define ('UPLOAD_ERR_OK', 0);
define ('UPLOAD_ERR_INI_SIZE', 1);
define ('UPLOAD_ERR_FORM_SIZE', 2);
define ('UPLOAD_ERR_PARTIAL', 3);
define ('UPLOAD_ERR_NO_FILE', 4);
define ('UPLOAD_ERR_NO_TMP_DIR', 6);
define ('UPLOAD_ERR_CANT_WRITE', 7);
define ('UPLOAD_ERR_EXTENSION', 8);

参照下,错误码为6对应为UPLOAD_ERR_NO_TMP_DIR即跟缓存目录有关

顺藤摸瓜,在php.ini配置文件中有个字段upload_tmp_dir允许设置上传文件临时目录

深究下php官网关于upload_tmp_dir的解释

upload_tmp_dir` string

The temporary directory used for storing files when doing file upload. Must be writable by whatever user PHP is running as. If not specified PHP will use the system's default.

If the directory specified here is not writable, PHP falls back to the system default temporary directory. If open_basedir is on, then the system default directory must be allowed for an upload to succeed.

从这里我们可以得知两个信息:

  1. 如果upload_tmp_dir为空则表示使用系统默认缓存目录,linux/tmp
  2. 如果php.ini或者nginx fastcgi.conf中设置了open_basedir,那么也必须开放upload_tmp_dir目录

看到这里焕然大悟:因为笔者之前在服务器配置的时候遇到了一个问题nginx搭建php提示No input file specified.,当时在fastcgi.conf中设置了open_basedir

解决问题

条件满足,现在让我们来一步步解决它

第一步:确认当前用户是否对upload_tmp_dir(linux默认为/tmp)有足够的访问权限

sudo chmod -R 777 /tmp

第二步:如果开启了open_basedir(笔者配置fastcgi.conf中),需一起开放upload_tmp_dir目录

fastcgi_param PHP_VALUE open_basedir=/opt/:/home/gitlab-runner/:/tmp/;

第三步:重启phpnginx(笔者服务器linux centos6.5)

service php-fpm restart
service nginx restart

再次请求图片上传接口就不再提示错误了

好了,问题解决~

happy coding!