当ajax验证时,Yii2上传字段始终为空

时间:2018-01-08 19:39:50

标签: php file-upload yii2 image-uploading

我上传文件有问题。我使用kartik-v / yii2-widget-fileinput扩展名。这是我的代码:

表单模型规则

/**
 * @inheritdoc
 */
public function rules()
{
    return [
        [['image'], 'required', 'on' => static::SCENARIO_CREATE],
        [['image'], 'file', 'extensions' => 'png, jpg, jpeg', 'maxSize' => 1024 * 1024],
    ];
}

表单视图

<?php $form = ActiveForm::begin([     
    'enableAjaxValidation' => true,
    'options' => ['enctype' => 'multipart/form-data']
]); ?>

 <?= $form->field($model, 'image')->widget(FileInput::classname(), [
            'options' => ['accept' => 'image/*'],
            'pluginOptions' => [
                'showPreview' => false,
                'showCaption' => true,
                'showRemove' => true,
                'showUpload' => false,
                'showCancel' => false
            ],            
        ]); ?>

控制器动作

 public function actionCreate()
{
    $model = new ItemForm();
    $model->scenario = ItemForm::SCENARIO_CREATE;

    if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
        Yii::$app->response->format = Response::FORMAT_JSON;
        return ActiveForm::validate($model);
    }

    if ($model->load(Yii::$app->request->post())) {

        $image = UploadedFile::getInstance($model, 'image');

        $randomString = Yii::$app->getSecurity()->generateRandomString(10);
        $name = Inflector::slug($model->title) . '_' . $randomString . '.' . $image->extension;

        $url = Image::URL . $name;

        $model->image = $name;          

        if ($model->save()) {
            $image->saveAs($url);
            return $this->redirect(['view', 'id' => $model->id]);
        }       
    } else {         
        return $this->render('create', [
            'model' => $model,             
        ]);
    }
}

总是当我提交表单时,我收到错误“需要图像字段”。我已阅读了很多教程,但在使用ajax验证时仍然遇到同样的问题。谁能看到它并告诉我我做错了什么?

1 个答案:

答案 0 :(得分:3)

修改

最重要的是,如果表单中有文件类型字段,则不应使用import cfscrape from bs4 import BeautifulSoup # log in scraper = cfscrape.CloudflareScraper() scraper.get('https://X.com/wp-login.php') tokens = cfscrape.get_tokens('https://X.com') browser = mechanicalsoup.StatefulBrowser(session=scraper, user_agent=tokens[1]) browser.select_form('#loginform') browser['log'] = 'X' browser['pwd'] = 'X' browser.submit_selected() browser.open('https://X.com/page/') 选项。请参阅此ISSUE使用enableAjaxValidation而不是

除了查看完整模型之外,您似乎正在尝试使用数据库表字段enableClientValidation作为相同字段来上传图像,因为您不应该这样做,您应该在您的内部声明自定义字段模型并使用它来上传文件并将新文件名分配给数据库字段image,目前您必须在模型中添加一些内容并更改代码

1。image这样的$file之后,在public $tags

之后,在模型顶部声明名称为public $myFile;的自定义字段

2. 更改验证规则

[['image'], 'file', 'extensions' => 'png, jpg, jpeg', 'maxSize' => 1024 * 1024],

以下

[['myFile'], 'file', 'extensions' => 'png, jpg, jpeg', 'maxSize' => 1024 * 1024],

[['image'], 'required', 'on' => static::SCENARIO_CREATE],

到这个

[['myFile','image'], 'required', 'on' => static::SCENARIO_CREATE],

3。在html表单中更改您的字段名称,从imagemyFile,即$form->field($model, 'image')更改为$form->field($model, 'myFile')

4. 对于actionuploadItemImage()功能内的更改,请参见下文,我已对其进行了更新。

您要将$name变量分配到$model->image字段

 $model->image = $name; 

并且在$name中它是一个字符串,而在模型中它应该是一个文件

 $name = Inflector::slug($model->title) . '_' . $randomString . '.' . $image->extension;

您应该做的是将上传文件的实例分配到模型字段image,然后调用$model->save()并使用自定义文件名saveAs(),更改您的{{ 1}}代码到以下

action

然后在模型中创建以下方法

public function actionCreate()
{
    $model = new ItemForm();
    $model->scenario = ItemForm::SCENARIO_CREATE;

    if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
        Yii::$app->response->format = Response::FORMAT_JSON;
        return ActiveForm::validate($model);
    }

    if ($model->load(Yii::$app->request->post())) {

        $model->myFile = UploadedFile::getInstance($model, 'myFile');
        $randomString = Yii::$app->getSecurity()->generateRandomString(10);
        $model->image = Inflector::slug($model->title) . '_' . $randomString . '.' . $model->myFile->extension;

        $model->uploadItemImage();
        if ($model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        }       
    } else {         
        return $this->render('create', [
            'model' => $model,             
        ]);
    }
}