ThinkPHP需引入华为云OBS官方SDK v3.22.12+封装ObsService类,禁用Filesystem OSS驱动;须配全协议Endpoint、编程访问密钥、同区域Bucket;上传大文件需手动分段,注意part≥5MB及uploadId清理。

ThinkPHP 怎么用华为云 OBS SDK 上传文件
直接结论:ThinkPHP 本身不内置 OBS 支持,必须引入华为云官方 PHP SDK(huaweicloud-sdk-php-obs),再封装成可复用的 Service 类。别试图用 ThinkPHP 的 Filesystem 驱动硬套 OBS——它不兼容 S3 协议,官方也明确不支持。
常见错误现象:Class 'ObsClient' not found、403 Forbidden(密钥权限不足)、Connection refused(Endpoint 写错或网络不通)。
- 必须使用华为云 OBS 官方 PHP SDK v3.22.12+(旧版已停更,且不支持 PHP 8.x)
- Endpoint 必须是完整域名,例如
https://obs.cn-north-4.myhuaweicloud.com,不能只写obs.cn-north-4.myhuaweicloud.com(缺协议会报 cURL error 1) - AccessKey 和 SecretKey 必须在华为云「我的凭证」中创建「编程访问」类型,不能用 IAM 用户密码或临时 token(除非你手动实现 STS 签名逻辑)
- Bucket 必须已存在且区域(Region)与 Endpoint 严格匹配,比如
cn-north-4的 bucket 不能用cn-east-2的 endpoint 访问
怎么封装一个 ObsService 类供 ThinkPHP 调用
建议放在 app/service/ObsService.php,避免耦合控制器。核心是把 ObsClient 实例化和常用操作(上传、删除、生成预签名 URL)抽出来。
关键点:
- 构造函数里传入配置数组,不要硬编码 AK/SK;从
config/obs.php加载更安全 - 上传方法推荐用
$obsClient->putObject(),不是putObjectFromStream()——后者对大文件容易内存溢出,前者支持分片自动降级 - 上传后务必检查返回的
$result['status']是否为 200,华为云 SDK 不抛异常,只返回数组 - 生成临时下载链接必须用
createSignedUrl(),且expires单位是秒(不是毫秒),超时后链接立即失效
示例片段(非完整类):
use Obs\ObsClient;
<p>class ObsService
{
protected $obsClient;</p><pre class="brush:php;toolbar:false;">public function __construct(array $config)
{
$this->obsClient = new ObsClient([
'key' => $config['access_key'],
'secret' => $config['secret_key'],
'endpoint' => $config['endpoint'],
]);
}
public function upload(string $bucket, string $objectKey, string $filePath): array
{
$result = $this->obsClient->putObject([
'Bucket' => $bucket,
'Key' => $objectKey,
'File' => $filePath,
]);
return ['success' => $result['status'] === 200, 'data' => $result];
}}
为什么不能用 ThinkPHP 的 Storage::disk('oss')?
因为 ThinkPHP 8.x 的 think-filesystem 自带的 oss 驱动只适配阿里云 OSS,其签名算法(OSS V1/V4)、Header 规范(x-oss- 前缀)、Endpoint 格式都和华为云 OBS 不兼容。强行改配置只会卡在 InvalidAccessKeyId 或 SignatureDoesNotMatch。
有人试过用 S3 兼容模式对接 OBS——华为云确实提供 S3 兼容接口,但需额外开通「S3 兼容访问」开关,并使用独立的 S3 Endpoint(形如 https://s3.cn-north-4.myhuaweicloud.com),且仍需调整鉴权方式。不如直接用原生 SDK 稳定。
- OBS 原生 SDK 对中文路径、特殊字符(空格、括号)支持更好;S3 模式下需手动
rawurlencode()objectKey - 华为云控制台的「日志跟踪」功能只对原生 OBS 接口生效,S3 接口日志不进 OBS 日志中心
- 如果项目已有大量
Storage::disk('oss')调用,建议新增一个obsdisk 驱动,而不是替换原有 oss 驱动
上传大文件(>100MB)要注意什么
OBS 原生支持分段上传(Multipart Upload),但 SDK 默认不会自动触发——putObject() 方法对超过 100MB 的文件会静默失败(返回 400 Bad Request),必须显式调用 initiateMultipartUpload + uploadPart + completeMultipartUpload 流程。
- 小文件(putObject() 最简单
- 中等文件(5–100MB):可用
putObject(),但要设置'bufferSize' => 5 * 1024 * 1024避免内存爆掉 - 大文件(>100MB):必须手写分段逻辑,SDK 的
ObsClient::uploadFile()方法已废弃,新版本只保留putObject()和底层分段接口 - 注意:分段上传的每个 part 必须 ≥ 5MB(最后一片除外),否则
uploadPart会报错EntityTooSmall
真正容易被忽略的是:华为云 OBS 的分段上传 ID(uploadId)有效期默认 7 天,但如果你上传中途失败又没调用 abortMultipartUpload,这个 uploadId 会一直占用,直到过期。大量残留 uploadId 可能影响 Bucket 的并发上传上限。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











