yii2框架中关于图片上传的中文文档只有一篇,基本上说了如何在框架内依赖activeform创建的表单来提交,而我们一般的上传个用户头像什么的,只需要上传图片,局部刷新即可。https://www.yiichina.com/doc/guide/2.0/input-file-upload官方文档中没有查找到资料。

那怎么办呢,在网络上搜各种资料,终于找了个原始的办法解决了。就是还没弄懂yii2 中 uploadfil帮助类的各种方法,所以目前我先弄了一个这种的方法,希望大神能够指导下,更安全的写代码。我的基本上这样的

视图(views)

    <img id="head" src="heading ? Yii::getAlias("@web").$model->heading : './upload/user/0/heading.png';?>" />

'uploadForm','options'=>['enctype'=>'multipart/form-data']]); ?>
                            上传图片

js代码是这样写的,提示信息用了 layer组件,也可以直接 alert,或者console.log()记录日志

$(document).ready(function(){
    layui.use(['layer'], function(){
        
        var layer = layui.layer;
    });
  //监听提交
    $("button#upload").click(function(){
        var formData = new FormData($("#uploadForm")[0]);
        $.ajax({
            data: formData,
            type: "post",
            url: "./index.php?r=admin/userhead",
            async:true,
            cache:false,
            contentType: false,
            processData: false,
            success: function(res){
                    if(res.status == 'true'){
                      layer.msg(res.info, {inon:1});
                      $("img#head").attr("src", res.url);
                
                    }else{
                      layer.msg(res.info, {icon:2});
                    }
            },
            error: function(res){
                      layer.msg('服务器错误');   
            }
        });
    return false; //阻止页面跳转  
  });
});

控制器里面是这样接收数据的

因为最后我发现,保存文件的时候yii2它需要一个uploadfile类对象

$file = new UploadedFile();
$file->name = $_FILES ["filepath"]['name'];
$file->tempName = $_FILES ["filepath"]['tmp_name'];
$file->type = $_FILES ["filepath"]['type'];
$file->size = $_FILES ["filepath"]['size'];
$file->error = $_FILES ["filepath"]['error'];
$model->filepath = $file;

最后我们在模型里面对 filepath 这个字段进行文件规则验证,这里呢没有用uploadfile 类是因为我们试着用哪几个常用的接收数据的方法都 接收不到ajax 提交过来的数据,所以就这么写了,这么写在接收 $_FILES['filepath']这个数据前要做一些必要的验证,防止数据造假,另外在 模型的验证规则里也把文件的规则尽量写详细一些,因为我们只需要一张图片,别把其它什么的文件传上来。

再来看看 视图到控制器的提交过程

FormData 提交的数据结构图

1549877250880.jpg

    从图中看,它除了提交 filepath 字段选择的文件信息外,也顺便把 yii2必要的验证参数隐藏的input标签的值也传上去了,有利于服务器代码的验证。

问题是解决了,但接受的控制器代码不是很好,这以后要再研究下 uploadfile这个类的各种方法。

最后关于图片数据的保存,在模型中写一个函数方法,或者参考官方文档的例子,直接用uploadfile类提供的方法即可保存,路径可能有必要自定义下

$this->filepath->saveAs('uploads/' . $this->filepath->baseName . '.' . $this->filepath->extension);

这样文件就保存到服务器上了。

我这种yii2 ajax post 提交上传图片文件到服务器的办法也可以用到其它类型文件的上传。

以后发现更好的办法了再来修改我这篇文章。