Yii框架本身不提供OSS存储能力,必须依赖扩展或SDK;推荐使用johnlui/aliyun-oss(兼容aliyun/oss-sdk-php v2.4.x),它将SDK封装为Yii2 Component,但不支持STS、分片上传、连接池与重试策略,需自行补全。

Yii 框架本身不提供 OSS 存储能力,必须靠扩展或 SDK 封装。直接用 johnlui/aliyun-oss 是最快路径,但得清楚它只做基础封装,不处理连接池、重试、STS 临时凭证这些——你得自己补。
为什么选 johnlui/aliyun-oss 而不是官方 SDK?
它把 aliyun/oss-sdk-php 包自动拉进来并注册为 Yii2 Component,省去手动 new OssClient 的样板代码。但注意:v3.x 版本的官方 SDK 有 breaking change,johnlui/aliyun-oss 当前兼容的是 v2.4.x;如果 composer 自动装了 v3,上传会报 Class 'OSS\OssClient' not found。
实操建议:
- 执行
composer require "johnlui/aliyun-oss:^2.0"(明确锁 v2) - 装完立刻跑
composer dump-autoload,避免 autoloader 缓存导致类找不到 - 别在配置里写
"aliyun/oss-sdk-php": "^3.0"—— 它和扩展不兼容
endpoint 和 bucket 配错会导致静默失败
常见现象:上传没报错,但文件根本没到 OSS,或者请求卡住几十秒后超时。原因多半是 endpoint 写成内网地址(如 oss-cn-hangzhou-internal.aliyuncs.com),而你的应用不在阿里云 ECS 上;或者 bucket 名含下划线或大写字母,触发 InvalidBucketName 异常但被吞掉。
正确写法:
-
endpoint必须带协议,且不含 bucket,例如https://oss-cn-hangzhou.aliyuncs.com -
bucket只写纯名称,如my-bucket-2026(全小写、短横线、无下划线) - 敏感参数不要硬编码进 config,统一放
params-local.php,再通过'accessKeyId' => Yii::$app->params['oss']['accessKeyId']注入
上传 key 路径怎么写才不踩坑?
OSS 没目录概念,key 就是完整字符串。传 /uploads/avatar.jpg 或 uploads/avatar.jpg 都能存,但前者在部分 CDN 回源或 SDK 签名时会被 trim 掉开头斜杠,行为不一致。
实操建议:
- 统一用相对路径:如
uploads/2026/04/abc123.jpg(不以/开头) - 文件名用 UUID 或时间戳 + 原扩展名,避开中文、空格、特殊符号
- 上传前调
$oss->exists($key)判断是否已存在;需要防重就加逻辑,不需要就跳过(OSS 默认覆盖) - 生成可访问 URL 时,优先用
$oss->getObjUrl($bucket, $key),而不是拼接https://$bucket.$endpoint/$key—— endpoint 可能带自定义域名,且私有 bucket 需要签名
最易被忽略的一点:OSS 的权限模型是基于 Bucket 和 Object 的,不是基于用户。如果你开了私有读写,又没配好签名 URL 有效期或 CDN 回源鉴权,前端拿到的链接会 403;但错误日志里往往只有 “AccessDenied”,没有具体提示哪一步漏了权限配置。


















