Yii2模型复制时上传文件无法同步的问题排查与解决
Yii2 模型复制时上传文件无法复制的问题解决
问题原因
UploadedFile对象仅单次请求有效:原模型中的imageFiles如果是UploadedFile类型对象,仅在原上传请求的生命周期内有效。查询已保存的模型时,这些对象指向的临时上传文件已不存在,直接复制给新模型无法执行saveAs操作。attributes数组不包含非数据库字段:$model->attributes仅包含模型对应数据库表的列,若imageFiles是模型用于处理上传的临时属性(而非数据库字段),不会被$model->attributes = $existingModel->attributes复制;即使手动复制,得到的也是失效的UploadedFile对象。
解决方案
核心思路:复制原模型已保存的物理文件到新模型目录,而非复制无效的UploadedFile对象。
修改复制动作代码
public function actionDuplicate($id) { $existingModel = $this->findModel($id); $model = new Task(); // 复制数据库字段属性 $model->attributes = $existingModel->attributes; // 重置主键 $model->id = null; if ($model->load(Yii::$app->request->post()) && $model->save()) { // 定义原模型与新模型的文件目录 $originalDir = Yii::getAlias('@doc_attivita') . "/" . $existingModel->id; $newDir = Yii::getAlias('@doc_attivita') . "/" . $model->id; // 创建新模型的文件存储目录 FileHelper::createDirectory($newDir, 0775, true); // 复制原模型文件到新目录 // 场景1:原模型的imageFiles字段存储了文件名数组 if (isset($existingModel->imageFiles) && is_array($existingModel->imageFiles)) { foreach ($existingModel->imageFiles as $fileName) { $originalFile = $originalDir . "/" . $fileName; if (file_exists($originalFile)) { copy($originalFile, $newDir . "/" . $fileName); } } // 更新新模型的imageFiles字段(若需存储文件名) $model->imageFiles = $existingModel->imageFiles; $model->save(false); // 跳过验证,仅更新字段 } // 场景2:原模型未存储文件名,直接读取原目录所有文件 else { $files = FileHelper::findFiles($originalDir); $fileNames = []; foreach ($files as $file) { $fileName = basename($file); copy($file, $newDir . "/" . $fileName); $fileNames[] = $fileName; } // 存储文件名到新模型 $model->imageFiles = $fileNames; $model->save(false); } return $this->redirect(['view', 'id' => $model->id]); } else { // 渲染创建表单时,传递原文件信息用于前端展示 return $this->render('create', [ 'model' => $model, 'originalFiles' => $existingModel->imageFiles, ]); } }
注意事项
- 若
imageFiles是模型的数据库字段(存储文件名列表),需确保它在模型rules()中被标记为安全属性,才能被$model->attributes = $existingModel->attributes正确复制。 - 若用户复制时上传了新文件,新模型的
upload()方法会自动处理新文件,上述代码仅负责复制原模型旧文件,两者无冲突。 - 复制文件时可添加异常处理(如文件不存在、权限不足),避免程序崩溃并记录错误日志。
内容的提问来源于stack exchange,提问作者Abdelilah Dahdahi
相关产品推荐
相关产品推荐

