如何更新包含文件字段的表单而不在Yii中重新上传文件?

时间:2014-08-09 11:47:43

标签: php yii

我想更新模型中的记录,它包含一个文件字段,这里是表单代码:

<div class="row">
        <?php echo $form->labelEx($model,'img'); ?>
        <?php echo CHtml::activeFileField($model,'img',array('width'=>25,'lentgh'=>25)); ?>
        <?php echo $form->error($model,'img'); ?>
</div>

这是控制器中的更新操作:

$model=$this->loadModel($id);

$img = $model->img;

        if(isset($_POST['Press']))
        {

            $model->attributes=$_POST['Press'];
            $model->img = $img;

            if(isset($_POST['Press']['img'])){
               if(!empty ($_POST['Press']['img']))        
                  $model->img = CUploadedFile::getInstance($model, 'img');

因此,如果用户没有上传图像,则不应更新img属性的值并且应该验证模型,但是每次单击“保存”并且img文件归档为空时我都会收到验证错误,因此我该如何解决这个问题?

4 个答案:

答案 0 :(得分:1)

您可以将csenario用作:

  array('image', 'file',  'types'=>'jpg,png,gif',
                        'maxSize'=>1024 * 1024 * 5,
                        'allowEmpty' => false, 'on'=>'insert'),
array('image', 'file',  'types'=>'jpg,png,gif',
                        'maxSize'=>1024 * 1024 * 5,
                        'allowEmpty' => true, 'on'=>'update'),

之后它将允许更新空字段

答案 1 :(得分:0)

表单验证由模型处理。 你可以在你的model.php中将filefield的imagefield设置为空,如下所示:

    array('image', 'file',  'types'=>'jpg,png,gif',
                            'maxSize'=>1024 * 1024 * 5,
                            'allowEmpty' => true),

编辑: 在覆盖对象的当前值之前,您可以检查文件是否为空

$imageUploadFile = CUploadedFile::getInstance($model, 'image');
if($imageUploadFile !== null){ // only do if file is really uploaded
    $imageFileName = mktime().$imageUploadFile->name;
    $model->image = $imageFileName;
}  

答案 2 :(得分:0)

面对同样的问题,这是我的解决方案。

但首先我将描述我如何使用模型。

基本POST处理

if (Yii::app()->request->getIsPostRequest()) {
    $basicForm->attributes = Yii::app()->request->getParam(get_class($basicForm));
    if ($basicForm->validate()) {
        $logo = CUploadedFile::getInstance($basicForm, "logo");
        if (!is_null($logo)) {
            try {
                // uploads company logo to S3
            } catch (\Exception $e) {
                // display any kind of error to the user or log the exception
            }
        }
        if ($basicForm->save(false))
            $this->refresh();
    }
}

我的logo字段包含规则["logo", "file", "mimeTypes" => ["image/png", "image/jpeg"], "allowEmpty" => true]

此规则允许我自由上传或不上传文件,如果我想更改另一个表单字段而不更改文件,则会清空模型的logo字段和我的数据库也是。

<强>问题

  

如果表单更新尝试更新另一个表单字段而不是文件

,则文件变为空

为什么会这样?

发生这种情况是因为file验证程序在模型的CUploadedFile字段中包含字符串时需要logo类型的对象。来自数据库的字符串,用于存储徽标的路径。字符串不是CUploadedFile。在if ($basicForm->validate())模型将logo字段重置为null后。

<强>解决方案

拥有验证规则,如果logo是炒作,则上传/重新上传文件``如果基本logo类型string则不执行任何操作。在这里,我将放置一个基本的“模型内”验证器,由您将它移动到单独的类等中。

public function checkFile($attribute, $params)
{
    $mimeTypes = isset($params["mimeTypes"]) ?$params["mimeTypes"] :[];
    $allowEmpty = isset($params["allowEmpty"]) ?$params["allowEmpty"] :false;
    /** @var CUploadedFile $value */
    $value = $this->{$attribute};

    if (!$allowEmpty && empty($value))
        $this->addError($attribute, "{$attribute} can not be empty");

    if (!empty($value)) {
        if (is_object($value) && CUploadedFile::class === get_class($value) && 0 < sizeof($mimeTypes)) {
            if (!is_array($value->type, $mimeTypes))
                $this->addError($attribute, "{$attribute} file is of wrong type");
        } elseif (!is_string($value)) {
            // we can die silently cause this error won't actually ever get to the user in normal use cases
            $this->addError($attribute, "{$attribute} must be of type either CUploadedFile or PHP string");
        }
    }
}

我将其称为checkFile,然后logo规则变为["logo", "checkFile", "mimeTypes" => ["image/png", "image/jpeg"], "allowEmpty" => true],

就是这样。请享用。

注意:我在这里作为一个例子。代码可能不完全正确,或者按原样使用......所有的东西...... :)

答案 3 :(得分:0)

我遇到了同样的问题。在我的用户模型中,有一个包含图像路径的字段,我想更新模型,并用fileField清除图像。

因此,我想到了解决方法-在$ tmp_variable中的操作“更新”开始时存储包含path_to_file 的字段,如果没有新的上载-只需将其设置在 save()之前:

public function actionUpdate($id)
{ 
    $request = Yii::app()->request;
    $model = $this->loadModel($id, 'YourModel');
    $tmpPathToImage = $model->your_path_to_file_in_model;
    $yourModelPost = $request->getPost('YourModel');

    if (!empty($yourModelPost)) {
        $model->setAttributes($yourModelPost);

        $fileSource = Yii::getPathOfAlias('webroot.uploads.yourModel');
        $imgTmp = CUploadedFile::getInstance($model, 'your_path_to_file_in_model');

        if ($imgTmp !== null) {
            $imgTmp->saveAs($fileSource.'/'.$imgTmp->name);
            $model->your_path_to_file_in_model = '/'.UPLOADS_YOUR_MODEL_FILE_PATH_RELATIVE.'/'.$imgTmp->name;
        }
        else {
            $model->your_path_to_file_in_model = $tmpPathToImage;
        }

        if ($model->save()) {
            $this->redirect(['/admin/yourModel/index']);
        }
    }

    $this->render('update', [
        'model' => $model,
    ]);
}

希望它可以帮助某人...:)