阿江 2017-10-03 07:02:46 4994次浏览 1条回复 0 0 0

说明

学习Yii Framework 2易2框架的过程是漫长的也是充满乐趣的以下是我学习Yii2框架时对官网英文资料(请参见原文网址)的翻译和代码实现提供了较完整的代码供你参考不妥之处请多多指正

原文网址:

http://www.yiiframework.com/doc-2.0/guide-input-file-upload.html

本文主题:文件上传(Uploading Files)

在Yii中上传附件通常使用yii\web\UploadedFile,它封装每个上传的文件为一个UploadedFile对象,结合yii\widgets\ActiveForm和模型,你可以很容易的实现安全的文件上传机制。

1、创建模型(Creating Models)

和文本输入框一样,上传单个文件需要先创建一个模型类,并使用一个模型属性来保存上传文件实例,你可能还需要声明一个验证规则去验证上传文件,例如:

namespace app\models;
use yii\base\Model;
use yii\web\UploadedFile;
class UploadForm extends Model{
	public $imageFile;
	public function rules(){
		return [
			[['imageFile'],'file','skipOnEmpty'=>false,'extensions'=>'png,jpg'],	
		];
	}
	public function upload(){
		if($this->validate()){
			$this->imageFile->saveAs('uploads/'.$this->imageFile->baseName.'.'.$this->imageFile->extension);
			return true;
		}else{
			return false;
		}
	}
}

上面的代码中,imageFile属性用于保存上传文件实例,它和file验证规则相关联,使用yii\validators\FileValidator以确保上传文件的扩展名是png或jpg。upload()方法会执行验证并保存上传文件到服务器。 file验证器允许你检查文件扩展名,文件大小,MIME类型,更多细节请参考Core Validators章节: http://www.yiiframework.com/doc-2.0/guide-tutorial-core-validators.html#file

小贴士:如果你上传的是一张图上,你可以使用image验证器,image验证器是yii\validators\ImageValidator,它将验证属性是否接收到了一个有效的图片,然后存储图片或使用Imainge扩展处理它。 Imainge扩展: https://github.com/yiisoft/yii2-imagine

2、渲染文件输入框(Rendering File Input)

下一步,需要在视图中添加一个文件输入框

<?php
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
    <?= $form->field($model, 'imageFile')->fileInput() ?>
    <button>Submit</button>
<?php ActiveForm::end() ?>

<? 需要记住的是你需要为表单添加一个enctype选项,以正确上传文件。fileInput()将渲染一个标签,这样客户就可以选择文件进行上传。

小贴士:自2.0.8版本起,当有文件输入框时,yii\web\widgets\ActiveField::fileInput将自动添加enctype到表单中。

3、连接起来(Wiring Up)

现在需要在控制器的动作中编写代码将模型和视图连接起来,共同完成文件上传:

namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\UploadForm;
use yii\web\UploadedFile;
class SiteController extends Controller{
    public function actionUpload(){
        $model = new UploadForm();
        if (Yii::$app->request->isPost) {
            $model->imageFile = UploadedFile::getInstance($model, 'imageFile');
            if ($model->upload()) {
                // file is uploaded successfully
                return;
            }
        }
        return $this->render('upload', ['model' => $model]);
    }
}

上述代码中,表单提交时,将调用yii\web\UploadedFile::getInstance()方法创建一个UploadedFile实例来表示上传的文件,然后我们依靠模型验证上传文件的有效性,然后存储文件到服务器。

4、上传多个文件(Uploading Multiple Files)

注意:多文件上传按钮点击后,要过一会儿才能弹出文件选择窗口,选中后、保存时也会等待较长时间。

//maxFiles,一次可上传的最大文件数 你可以一次上传多个文件,只需要将前述代码进行一些改动即可。 首先你需要调整模型类,在file验证规则中添加maxFiles来限制可上传的最大文件数,将maxFiles设置为0意味着不限制同时上传的文件数量。同时可上传的文件最大数量也受PHP的参数max_file_uploads的限制,其默认值是20。 其次还需要将upload()方法修改,将多个上传的文件一个一个进行处理。

namespace app\models;
use yii\base\Model;
use yii\web\UploadedFile;
class UploadForm extends Model{
    /**
     * @var UploadedFile[]
     */
    public $imageFiles;
    public function rules(){
        return [
            [['imageFiles'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg', 'maxFiles' => 4],
        ];
    }    
    public function upload(){
        if ($this->validate()) { 
            foreach ($this->imageFiles as $file) {
                $file->saveAs('uploads/' . $file->baseName . '.' . $file->extension);
            }
            return true;
        } else {
            return false;
        }
    }
}

在视图文件中,你需要在fileInput()中添加multiple选项,这样表单上传框才能接受多个文件。

<?php
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
    <?= $form->field($model, 'imageFiles[]')->fileInput(['multiple' => true, 'accept' => 'image/*']) ?>
    <button>Submit</button>
<?php ActiveForm::end() ?>

最后,需要在控制器的动作中调用UploadedFile::getInstances(),而不是UploadedFile::getInstance(),这样就可以将一个UploadedFile数组实例赋给UploadedForm::imageFiles。

namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\UploadForm;
use yii\web\UploadedFile;
class SiteController extends Controller{
    public function actionUpload(){
        $model = new UploadForm();
        if (Yii::$app->request->isPost) {
            $model->imageFiles = UploadedFile::getInstances($model, 'imageFiles');
            if ($model->upload()) {
                // file is uploaded successfully
                return;
            }
        }
        return $this->render('upload', ['model' => $model]);
    }
}

(全文完)

您需要登录后才可以回复。登录 | 立即注册