我想更新模型中的记录,它包含一个文件字段,这里是表单代码:
<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文件归档为空时我都会收到验证错误,因此我该如何解决这个问题?
答案 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,
]);
}
希望它可以帮助某人...:)