当我尝试在我的模型的多个实例(表格方式)中上传多个文件时,我遇到了一些问题。
我有一个名为Files的模型和一个为该模型的多个实例生成表单的视图。当我保存没有"multipart/form-data"的表单时,一切正常,但是如果我将这个参数放在表单上并提交它,验证将显示"File不能为空"的消息。
请看下面我的控制器代码:
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);
}
}
我已经尝试了所有的方法,但是我不能解决它,有什么建议吗?
谢谢。
我不确定这个分配$models[$k]->attributes = $form;
是否会为您的模型做$_FILES以及$_POST。看看这个例子,我认为你需要在validate()
或save()
(也验证)之前做CUploadedFile
的东西,否则你的文件字段将是空白的。
我认为你需要这样的事件顺序:
-
$model->save()
或$model->validate()
//然后验证 -
$model->$field->saveAs($path . $model->$field);
//然后保存文件
$model->$field = CUploadedFile::getInstance($model, $field);
//设置文件字段当前的事件顺序是这样的:
-
$model->save()
和$model->validate()
-
$model->$field = CUploadedFile::getInstance($model, $field);
-
$model->$field->saveAs($path . $model->$field);
我可能离得太远了,我只是在看你的代码,并没有实际测试这个。此外,我不知道为什么当你在表单上设置multpart/form-data
属性时,它只会抛出错误;没有这个,它根本就不应该工作!也许它跳过了对文件字段的验证?或者attributes()
从$_POST中分配文件以外的东西?/耸耸肩
更新:
另一件可能发生的事情是,使用"表格"输入,您需要引用输入字段'$key'(即Model[0][imageFile]
)。这里,你调用的地方:
$this->upload_file($model, "file");`
您可能需要调用这样的东西,以便getInstanceByName()
获得正确的字段名称:
$this->upload_file($model, "[".$k."]file");`
我认为你仍然需要重新安排你的代码,正如我上面提到的。
祝你好运!
更多阅读:
- Yii论坛关于这个主题的帖子
- 您在Yii论坛上的相同问题