必须让文件保存路径与CDN回源路径严格对齐,并返回CDN域名URL;需定义@uploadPath别名、改造upload()方法生成日期子目录与唯一文件名、保存本地后拼接CDN前缀URL,同时适配fileinput删除URL及大文件流式上传的预热刷新。

要在Yii2项目中让上传的文件自动走CDN加速,必须让文件保存路径与CDN回源路径严格对齐,同时确保生成的URL不指向本地webroot而是CDN域名,否则用户访问的仍是源站静态资源,CDN形同虚设。
配置CDN回源路径与本地上传目录映射
登录CDN控制台,在「回源配置」中将回源域名设为你的Yii2应用域名(如 https://api.example.com),回源路径设为 /uploads/;同时确认该路径在服务器上真实存在且Web服务有读取权限。
在 /common/config/bootstrap.php 中添加别名定义:Yii::setAlias('@uploadPath', dirname(dirname(__DIR__)) . '/frontend/web/uploads');
这一步必须做,否则后续所有上传逻辑都会找不到写入位置,【@uploadPath别名未定义会导致upload()方法抛出InvalidParamException】。
改造上传模型:支持动态子目录+CDN前缀
修改 UploadForm 模型的 upload() 方法:
第一步:根据日期生成子目录路径,避免单目录下文件过多:$path = Yii::getAlias('@uploadPath') . '/' . date('Y/m/d');
第二步:创建目录并确保可写:\yii\helpers\FileHelper::createDirectory($path, 0755, true);
第三步:生成唯一文件名,防止重名覆盖:$fileName = uniqid() . '.' . $this->imageFile->extension;
第四步:保存文件到本地磁盘:$this->imageFile->saveAs($path . '/' . $fileName);
第五步:返回带CDN域名的完整URL,而非本地相对路径:return 'https://cdn.example.com/uploads/' . date('Y/m/d') . '/' . $fileName;
使用kartik-v/yii2-widget-fileinput时注入CDN域名
方法一:在视图中配置 initialPreviewConfig 的 url 字段,强制替换为CDN地址
方法二:在控制器返回JSON响应时,将 file.url 字段值替换为CDN前缀路径,例如把 /uploads/2026/08/06/abc.png 改为 https://cdn.example.com/uploads/2026/08/06/abc.png
注意:插件默认会用 Url::to() 生成删除URL,若未重写该行为,删除请求仍将发往源站,【务必在pluginOptions中设置deleteUrl为CDN网关代理地址,否则删除操作失效】。
RESTful接口大文件流式上传适配CDN
对于视频、安装包等超大文件,必须绕过 $_FILES,改用 php://input 流式接收:
① 在控制器中禁用 multipart 解析器:'parsers' => [] 或移除 Content-Type: multipart/form-data 对应的解析器
② 打开输入流:$input = fopen('php://input', 'rb');
③ 按8KB分块写入本地临时路径:fwrite($output, fread($input, 8192));
④ 文件写完后,立即调用CDN厂商提供的API触发预热或刷新缓存,确保首次访问不回源——这一步不能省,否则首屏加载仍慢
⑤ 返回CDN可直接访问的URL,格式为 https://cdn.example.com/{bucket}/{object-key},其中 object-key 必须与你上传到本地的路径结构一致


















