代码之家  ›  专栏  ›  技术社区  ›  user794846

Yii 2如何在文件上载时添加自定义验证检查

  •  0
  • user794846  · 技术社区  · 7 年前

    我正在构建一个CSV上传程序,我想添加一个自定义验证功能,该功能将检查CSV文件的标题行,以确保正确的列已就位。

    我试图在模型中加入一个自定义的验证规则来实现这一点,但在第一个障碍上失败了。

    我正在

    正在设置未知属性:yii\validators\FileValidator::0

    例外,但据我从文档中所知,这应该是可行的。

    Model

    /**
    * UploadForm is the model behind the upload form.
    */
    class UploadForm extends Model
    {
    /**
     * @var UploadedFile file attribute
     */
    public $file;
    
    /**
     * @return array the validation rules.
     */
    public function rules()
    {
        return [
            [['file'], 'file', 'extensions' => 'csv', 'checkExtensionByMimeType'=>false, 'headerCheck', 'skipOnEmpty' => false]
        ];
    }
    
    public function attributeLabels(){
        return [
            'file'=>'Select csv'
        ];
    }
    
     function headerCheck($attribute, $params, $validato){
    
        $this->addError($attribute, "error");
    }
    }
    

    Controller 功能:

         public function actionUpload()
    {
        $model = new UploadForm();
    
        if (Yii::$app->request->isPost) {
            $model->file = UploadedFile::getInstance($model, 'file');
            $filename = $model->file->baseName . '.' . $model->file->extension;
    
            if ($model->file && $model->validate()) {
                $upload = $model->file->saveAs('uploads/'.$filename );
    
                if($upload){
                    define('CSV_PATH','uploads/');
                    $csv_file = CSV_PATH . $filename;
                    $filecsv = file($csv_file);
    
                    foreach($filecsv as $data){
                        $lines = explode(',',$data);
                        $t=1;
                    }
                }
            }
        }
    
        return $this->render('csvUpload', ['model' => $model]);
    }
    

    View

    <?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
    
    <?= $form->field($model, 'file')->fileInput() ?>
    
    <button>Submit</button>
    
    <?php ActiveForm::end() ?>
    

    为什么是 headerCheck() 没有作为自定义验证函数提取?

    1 回复  |  直到 7 年前
        1
  •  0
  •   ethan    7 年前

    简短回答

    你的规则应该这样写:

    return [
        [['file'], 'file', 'extensions' => 'csv', 'checkExtensionByMimeType'=>false, 'skipOnEmpty' => false],
        [["file"], "headerCheck"],
    ];
    

    请注意,您的验证规则“headerCheck”是数组中的一个单独项。

    冗长的回答

    规则的结构如下:

    [["attributes_to_validate"],"vaildatorCallback","param1"=>"value","param2"=>"value]
    

    请注意,前两项分别是属性和回调,然后可以指定应分配给验证器或传递给验证器回调的参数。这些参数的格式应为键是属性的名称,值是要分配给属性的值。

    在您提供的示例中,Yii看到您想要使用“文件”验证器,因此它创建了Yii\validators\FileValidator的一个实例。然后,它会看到您希望将参数“extensions”设置为“csv”,因此: yii\validators\FileValidator::$extensions = "csv"; 但是,由于在数组的这一部分中包含了自定义验证器,它认为“headerCheck”实际上是要分配给验证器的属性的值。由于您输入的“param”没有键,因此键默认为0,因此Yii认为您要分配的属性称为“0”。因此,Yii尝试: yii\validators\FileValidator::0 = "headerCheck";

    当然,FileValidator上没有属性“0”,因此您得到的错误来自于此。

    推荐文章