必须完成服务端凭证生成、文件流上传、url拼接三步闭环,漏掉任一环节会导致前端空白或403错误;需配置七牛云密钥、sdk组件及上传逻辑(支持$_files和base64),并做好cors与php上传限制适配。

要在Yii2项目中实现用户上传图片到七牛云OSS并返回可访问链接,必须完成服务端凭证生成、文件流上传、URL拼接三步闭环,漏掉任一环节都会导致前端显示空白或403错误。
前期准备:获取七牛云三要素
登录七牛云官网完成实名认证 → 进入「对象存储」→ 点击「创建空间」→ 命名空间(如myapp-prod)、选择区域(华南选south_china,华东默认east_china)→ 访问控制选「公开」→ 保存后进入该空间详情页,复制「空间域名」(形如http://p89z1x2y7.bkt.clouddn.com)→ 鼠标悬停头像 → 「密钥管理」→ 复制AccessKey和SecretKey。
【AccessKey和SecretKey绝不能写死在控制器里,必须通过环境变量或配置文件加载】
安装SDK并注册组件
编辑项目根目录下的composer.json,在"require"节点内添加:"crazyfd/yii2-qiniu": "dev-master" → 执行composer update → 在config/web.php的components数组中追加:
'qiniu' => [<br> 'class' => 'crazyfd\qiniu\Qiniu',<br> 'accessKey' => getenv('QINIU_ACCESS_KEY') ?: 'your_ak',<br> 'secretKey' => getenv('QINIU_SECRET_KEY') ?: 'your_sk',<br> 'domain' => getenv('QINIU_DOMAIN') ?: 'http://xxx.bkt.clouddn.com',<br> 'bucket' => getenv('QINIU_BUCKET') ?: 'myapp-prod',<br> 'region' => 'south_china'<br>],
这一步完成后,\Yii::$app->qiniu即可全局调用。
编写上传逻辑(支持表单文件+Base64)
方法一:处理$_FILES上传的临时文件
在控制器中新增actionUpload:
public function actionUpload()<br>{<br> if (\Yii::$app->request->isPost) {<br> $file = \Yii::$app->request->getUploadedFile('file');<br> if (!$file) {<br> throw new \yii\web\HttpException(400, '未检测到上传文件');<br> }<br> $key = 'uploads/' . date('Y/m/d/') . uniqid() . '.' . $file->extension;<br> $result = \Yii::$app->qiniu->uploadFile($file->tempName, $key);<br> if ($result['status'] === 200) {<br> $url = \Yii::$app->qiniu->getLink($key);<br> return json_encode(['code' => 0, 'url' => $url]);<br> } else {<br> return json_encode(['code' => -1, 'msg' => $result['message']]);<br> }<br> }<br>}
方法二:接收前端传来的Base64字符串(适用于富文本粘贴图)
提取Base64头之后的纯数据部分,用base64_decode()转为二进制 → 用tempnam(sys_get_temp_dir(), 'qiniu_')创建临时文件 → file_put_contents()写入 → 调用uploadFile()上传 → 删除临时文件。
注意:Base64方式必须校验data:image/png;base64,前缀,否则会因格式错误导致uploadFile内部抛出Warning: file_get_contents(): failed to open stream。
前端调用与跨域适配
第一步:确保Nginx/Apache已开启CORS,在响应头中加入:Access-Control-Allow-Origin: *(生产环境请替换为具体域名);
第二步:前端使用FormData提交,不要用JSON.stringify包裹文件字段;
第三步:若上传大文件(>5MB),需在php.ini中调整upload_max_filesize和post_max_size,否则PHP会在到达Yii2之前就截断请求。
第四步:测试时用Postman发送POST /index.php?r=site%2Fupload,Body选form-data,Key填file,Value选文件。











