我有一个表单来更新我的新闻帖子,该表单在同一页面上具有标题,内容和图像上传按钮。图片上传者使用Ajax方法将Kartik FileINput小部件用于Yii2。
这是我处理了AJAX上传的actionUpload
public function actionUpload($id)
{
$model = $this->findModel($id);
$currentImage=$model->image;
if (Yii::$app->request->isAjax)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$image = $model->uploadImage();
if($image===false)
{
//echo "image instance is empty";
$model->image = $currentImage;
}
if ($model->validate() && $model->save())
{
if($image !== false)
{
$model->image = $image->basename.'.'.$image->extension;
$image->saveAs('uploads/batam/'.$model->image);
$model->save(false);
return \yii\helpers\Json::encode(array("image" => $model->image,
));
}
}
else
{echo "validation failed";}
}
}
这是我在表单中提交的小部件文件上传(注意:它位于活动表单中)
echo FileInput::widget([
'name' => 'image',
'options'=>[
'multiple'=>false
],
'pluginOptions' => [
'uploadUrl' => Url::to(['news/upload','id'=>$id]),
'uploadExtraData' => [
'id'=>$id,
],
'initialPreview'=>[
Yii::getAlias('@web').'/uploads/batam'.$model->image
],
'initialPreviewAsData'=>true,
'overwriteInitial'=>false,
'maxFileSize'=>2800
]
]);
这是我的模型规则和uploadImage方法
public function rules()
{
return [
[['title', 'content'], 'required'],
[['content'], 'string'],
[['created_at', 'updated_at'], 'safe'],
[['image'], 'file','skipOnEmpty'=>true, 'extensions'=>'jpg,png,jpeg'],
[['title'], 'string', 'max' => 255],
];
}
public function uploadImage() {
$image = UploadedFile::getInstanceByName('image');
if (empty($image)) {
return false;
}
return $image;
}
我这里有2个问题需要帮助:
1.验证规则无效。我可以上传具有任何扩展名的任何文件,并且已成功在数据库中上传并更新了文件
2.图片上传包含在活动表单中,因此使用AJAX成功上传后,当我按“更新”按钮时,图片将不会显示。 image
字段被视为空白,因此update
按钮的行为就像我更新了空白图像一样。在我的数据库中,相关的news-id
的AJAX上载文件的图像路径已成功存储,并且该文件已上载。
如何解决呢?实际上,我不介意上载方法是否不使用AJAX而是仅使用带有post
的普通,单一表单提交方法,从而省略了upload
ajax按钮,但是根据Kartik纪录片,如果我想要使用显示先前存储的图像的小部件,它需要Ajax。
我在StackOverflow等中环顾了一些类似的问题,但是它们都在Ajax调用方法中出现空图像实例的问题(嗯,我以前也遇到过同样的问题,但是我在我的ajax上应用了Formdata之后,研究),虽然我对ajax调用中的空实例没有问题,但是在普通表单上提交时却有空实例。
这是我的actionUpdate
public function actionUpdate($id)
{
$model = $this->findModel($id);
$image= UploadedFile::getInstanceByName('image');
if ($model->load(Yii::$app->request->post()) && $model->save() ){
var_dump($image);exit();
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
谢谢!
答案 0 :(得分:0)
首先,验证器不起作用的原因是因为您不是从模型中创建文件输入窗口小部件,所以必须以这种方式进行操作,以使类模型中的规则起作用:
echo $form->field($model, 'image')->widget(FileInput::classname(), [
'options' => ['accept' => 'image/*'],
]);
然后,我不知道数据库的结构,但是我对如何处理图像上传提出了建议。首先,是在与数据库的图像字段分开的类内创建一个公共变量,该公共图像变量将是实例化窗体上的小部件的变量,也是具有规则的变量。这样,当您发布表单时,数据库中的image字段将不会被覆盖。
因此,当您使用ajax上传时,您也将发送对象的ID,并且在完成所有设置后,在上传功能中,您将存储路径,图像或图像的任何内容。数据库。