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

m4pnthwp  于 2022-11-09  发布在  其他
关注(0)|答案(4)|浏览(155)

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

<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文件字段为空,那么我如何解决这个问题?

pb3skfrl

pb3skfrl1#

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

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;
}
lymgl2op

lymgl2op2#

您可以将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'),

之后,它将允许在更新时为空字段

9udxz4iz

9udxz4iz3#

面对同样的问题,这里是我的解决方案。
但首先我将描述我是如何处理模型的。

基本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字段和我的数据库。

问题

如果表单更新尝试更新另一个表单字段,而不是文件,则文件为空
"为什么会这样"
发生这种情况是因为当模型的logo字段中有字符串时,file验证器需要CUploadedFile类型的对象。字符串来自存储徽标路径的数据库。而字符串不是CUploadedFile。并且在if ($basicForm->validate())模型之后,将logo字段重置为空。

解决方案

拥有验证规则,如果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],
就这样。好好享受。
注意:我把这个作为一个例子放在这里。代码可能不完全正确,或者按原样使用,所有的东西都是这样的...:)

whhtz7ly

whhtz7ly4#

我有同样的问题。在我的用户模型中有一个包含图像路径的字段,我想更新模型和文件字段清除我的图像。
因此,我想出了解决办法-将包含path_to_file的字段存储在$tmp_variable中的操作“update”的开头,如果没有新的上传-只需在**保存():**之前设置它

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,
    ]);
}

希望对某人有帮助...:)

相关问题