Yii 2 如何在文件上传时添加自定义验证检查
Yii 2 How add a custom validation check on file upload
我正在构建一个 CSV 上传器,我想添加一个自定义验证函数来检查 CSV 文件的 header 行以确保正确的列就位。
我正在尝试在模型中放置一个自定义验证规则来执行此操作,但在第一个障碍上失败了。
我得到
Setting unknown property: 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()
没有被选为自定义验证函数?
简答
你的规则应该这样写:
return [
[['file'], 'file', 'extensions' => 'csv', 'checkExtensionByMimeType'=>false, 'skipOnEmpty' => false],
[["file"], "headerCheck"],
];
请注意,您的验证规则 "headerCheck" 是数组中的一个单独项目。
长答案
一个规则的结构是这样的:
[["attributes_to_validate"],"vaildatorCallback","param1"=>"value","param2"=>"value]
请注意前两项分别是属性和回调,然后您可以指定应分配给验证器或传递给验证器回调的参数。这些参数应以一种形式出现,其中键是 属性 的名称,值是分配给 属性.
的值
在您提供的示例中,Yii 发现您想要使用 "file" 验证器,因此它创建了一个 yii\validators\FileValidator 的实例。然后它看到您希望将参数 "extensions" 设置为 "csv",因此它执行了:yii\validators\FileValidator::$extensions = "csv";
但是随后,因为您在数组的这一部分包含了自定义验证器,它认为"headerCheck" 实际上是要分配给验证器的 属性 的值。因为你输入的 "param" 没有键,键默认为 0 所以 Yii 认为你要分配的 属性 被称为'0'。因此,Yii 尝试这样做:yii\validators\FileValidator::0 = "headerCheck";
当然,FileValidator 上没有 属性 '0',所以这就是您收到的错误的来源。
我正在构建一个 CSV 上传器,我想添加一个自定义验证函数来检查 CSV 文件的 header 行以确保正确的列就位。
我正在尝试在模型中放置一个自定义验证规则来执行此操作,但在第一个障碍上失败了。
我得到
Setting unknown property: 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()
没有被选为自定义验证函数?
简答
你的规则应该这样写:
return [
[['file'], 'file', 'extensions' => 'csv', 'checkExtensionByMimeType'=>false, 'skipOnEmpty' => false],
[["file"], "headerCheck"],
];
请注意,您的验证规则 "headerCheck" 是数组中的一个单独项目。
长答案
一个规则的结构是这样的:
[["attributes_to_validate"],"vaildatorCallback","param1"=>"value","param2"=>"value]
请注意前两项分别是属性和回调,然后您可以指定应分配给验证器或传递给验证器回调的参数。这些参数应以一种形式出现,其中键是 属性 的名称,值是分配给 属性.
的值在您提供的示例中,Yii 发现您想要使用 "file" 验证器,因此它创建了一个 yii\validators\FileValidator 的实例。然后它看到您希望将参数 "extensions" 设置为 "csv",因此它执行了:yii\validators\FileValidator::$extensions = "csv";
但是随后,因为您在数组的这一部分包含了自定义验证器,它认为"headerCheck" 实际上是要分配给验证器的 属性 的值。因为你输入的 "param" 没有键,键默认为 0 所以 Yii 认为你要分配的 属性 被称为'0'。因此,Yii 尝试这样做:yii\validators\FileValidator::0 = "headerCheck";
当然,FileValidator 上没有 属性 '0',所以这就是您收到的错误的来源。