Yii验证表格形式无法上传文件

时间:2011-10-04 17:50:27

标签: php yii

当我尝试在模型的多个实例中上传多个文件时,我遇到了一些问题(表格方式)。

我有一个名为Files的模型和一个为该模型的多个实例生成表单的视图。当我在没有“multpart / form-data”的情况下保存表单时,一切正常,但是如果我将此参数放在表单上并提交它,则验证会显示“文件不能为空”的消息。

请参阅我的控制器代码:

public function actionRegistration() {
  $company  = new Company;
  $contacts = $this->getModelItens('Contact', 3);
  $banks    = $this->getModelItens('Bank'   , 2);
  $files    = $this->getModelItens('File'   , 2);

  $company->scenario = 'create';
  if($_POST['Company']) {
    $company->attributes = $_POST['Company'];
    $valid = $company->validate();
    $valid = $this->validateModels($_POST['Contact'], $contacts) && $valid;
    $valid = $this->validateModels($_POST['Bank'], $banks) && $valid;
    $valid = $this->validateModels($_POST['File'], $files) && $valid;

    if($valid) {
      if($company->save()) {
        $this->saveModels($contacts, $company->id);
        $this->saveModels($banks, $company->id);
        $this->saveModels($files, $company->id);

        $this->redirect('/obrigado');
      }
    }
  }

    $this->render('registration', array('company' => $company, 'contacts' => $contacts, 'banks' => $banks, 'files' => $files));
  }


private function getModelItens($model_name, $times, $scenario = 'create') {
  $models = array();
  for($i = 0; $i < $times; $i++) { 
    $models[$i]           = new $model_name; 
    $models[$i]->scenario = $scenario;
  }
  return $models;
}

private function validateModels($forms, $models) {
  $valid  = true;
  foreach($forms as $k => $form) { 
    $models[$k]->attributes = $form;
    $models[$k]->position   = $k;
    $valid = $models[$k]->validate() && $valid;
  }
  return $valid;
}

private function saveModels($models, $company_id) {
  foreach($models as $k => $model) {
    $model->company_id = $company_id;
    if($model instanceOf File) {
      if($model->save()) $this->upload_file($model, "file"); 
    } else $model->save();
  }
}


private function upload_file($model, $field, $k) {
  $path = Yii::app()->basePath . "/../assets/files/companies/{$model->company_id}/";

  $file = CUploadedFile::getInstance($model, $field);
  if($file instanceof CUploadedFile) $model->$field = $file;

  if($model->$field instanceof CUploadedFile) {
    if(!file_exists($path)) exec("mkdir -p {$path}");
    $model->$field->saveAs($path . $model->$field);
  }
}

我已经尝试了一切但我无法修复它,有什么建议吗?

感谢。

1 个答案:

答案 0 :(得分:0)

我不确定此作业$models[$k]->attributes = $form;是否会为您的模型执行$ _FILES以及$ _POST。查看this example,我认为您需要在CUploadedFilevalidate()(也验证)之前执行save()项内容,否则您的文件字段将为空白。

我认为你需要这个事件顺序:

  1. $model->$field = CUploadedFile::getInstance($model, $field); //设置文件字段
  2. $model->save()$model->validate() //然后验证
  3. $model->$field->saveAs($path . $model->$field); //然后保存文件
  4. 相反,您目前拥有以下事件顺序:

    1. $model->save()$model->validate()
    2. $model->$field = CUploadedFile::getInstance($model, $field);
    3. $model->$field->saveAs($path . $model->$field);
    4. 我可能会离开,我只是看着你的代码而不是实际测试它。此外,我不知道为什么它只在表单上设置multpart/form-data属性时抛出错误;没有它,它根本不应该工作!也许它没有那个在文件字段上跳过验证?或者attributes()除了文件之外还分配了$ _POST的内容? /耸肩

      <强>更新
      另一件可能发生的事情是,使用“表格”输入时,您还需要使用“$ key”引用输入字段(即Model[0][imageFile])。所以在这里,你打电话的地方:

      $this->upload_file($model, "file");`
      

      您可能需要调用类似的内容,以便getInstanceByName()获得正确的字段名称:

      $this->upload_file($model, "[".$k."]file");` 
      

      我认为您仍然需要重新安排您的代码,如上所述。

      祝你好运!

      更多阅读:

      1. Yii forum post about this subject
      2. Your same question in the Yii forum