yii2中通过模块化实现文件上传版本控制,v1和v2模块隔离命名空间、配置与存储路径,各自独立定义验证规则、保存逻辑及多文件支持策略。

你需要在Yii2项目中为上传文件功能添加版本控制,避免新旧上传逻辑混用、接口行为不一致、历史文件处理路径失效等问题。
用模块隔离不同版本的上传逻辑
每个上传版本对应一个独立module,例如v1和v2,天然隔离命名空间、配置、验证规则与存储路径。
第一步:在config/web.php的modules配置中添加:
'v1' => ['class' => 'api\modules\v1\Module'], 'v2' => ['class' => 'api\modules\v2\Module']
第二步:创建目录api/modules/v1/Module.php,内容必须显式声明controllerNamespace:
【controllerNamespace必须写全路径,否则会fallback到默认命名空间导致404】
namespace api\modules\v1; class Module extends \yii\base\Module { public $controllerNamespace = 'api\modules\v1\controllers'; }
第三步:在v1/controllers/UploadController.php中实现基础上传逻辑,v2下复用相同控制器名但代码完全独立——改v2不影响v1。
上传模型按版本定义验证与保存行为
v1版本只允许jpg/png,保存到uploads/v1/;v2版本支持webp/svg,校验MIME+扩展名双重匹配,并自动重命名防冲突。
方法一(v1模型):
namespace api\modules\v1\models; use yii\base\Model; use yii\web\UploadedFile; class UploadForm extends Model { public $imageFile; public function rules() { return [[['imageFile'], 'file', 'extensions' => 'jpg, png', 'maxSize' => 2097152]]; } public function upload() { if ($this->validate()) { $path = 'uploads/v1/' . date('Ymd') . '/'; @mkdir($path, 0755, true); $this->imageFile->saveAs($path . $this->imageFile->baseName . '.' . $this->imageFile->extension); return true; } return false; } }
方法二(v2模型):
namespace api\modules\v2\models; use yii\base\Model; use yii\web\UploadedFile; class UploadForm extends Model { public $imageFile; public function rules() { return [[['imageFile'], 'file', 'extensions' => 'jpg, png, webp, svg', 'mimeTypes' => 'image/jpeg, image/png, image/webp, image/svg+xml', 'maxSize' => 5242880]]; } public function upload() { if ($this->validate()) { $path = 'uploads/v2/' . date('Y/m/d') . '/'; @mkdir($path, 0755, true); $filename = uniqid() . '_' . time() . '.' . $this->imageFile->extension; $this->imageFile->saveAs($path . $filename); return $filename; } return false; } }
前端请求自动路由到对应版本
用户无需手动拼接版本路径,统一入口由URL规则解析版本号并透传。
在config/web.php的urlManager→rules中添加:
'POST api/upload' => 'v<version>/upload/upload',</version>
然后在api/modules/v1/controllers/UploadController.php和v2同位置的控制器里,接收$version参数即可做差异化日志或降级处理。
注意:不要把版本塞进action ID(如actionV2Upload),否则Gii无法生成、路由规则爆炸、行为继承混乱。
多文件上传按版本启用不同限制
v1仅支持单文件上传;v2开放多文件且限制总数与单个大小。
方法一(v1表单):
=$form->field($model, 'imageFile')->fileInput()?> //无multiple属性,强制单选
方法二(v2表单):
=$form->field($model, 'files[]')->fileInput(['multiple' => true])?>
v2模型需设置'maxFiles' => 10,并在rules()中将files声明为数组类型属性:
public $files = [];
return [[['files'], 'file', 'maxFiles' => 10, 'extensions' => 'pdf, docx']];
这一步必须写,否则UploadedFile::getInstances()拿不到数组实例,直接报错。











