'您的SecretId', * 'AccessKeySecret' => '您的SecretKey', * 'Bucket' => '存储桶名称', * 'Region' => '存储桶地域', * 'Domain' => '自定义域名' * ] */ public function __construct(array $config) { // 初始化基础配置 $this->bucket = $config['Bucket']; $this->region = $config['Region']; $this->domain = $config['Domain']; // 创建COS客户端实例 $this->cosClient = new Client([ 'region' => $this->region, // 地域 'schema' => 'https', // 使用HTTPS协议 'credentials' => [ // 鉴权凭证 'secretId' => $config['AccessKeyId'], 'secretKey' => $config['AccessKeySecret'], ], ]); } /** * 通过文件路径上传到COS(适合表单上传场景) * * @param string $tempPath 本地临时文件路径(如:/tmp/upload_xxxx.jpg) * @param string $fileType 文件扩展名(如:jpg) * @param string $prefix 存储路径前缀(默认:topic) * * @return array [ * 'cos_key' => 'COS存储路径', * 'full_url' => '完整访问URL', * 'location' => 'COS返回的Location' * ] * * @throws \Exception 上传失败时抛出异常 */ public function uploadFilePath(string $tempPath, string $fileType, string $prefix = 'topic'): array { try { // 生成唯一存储路径(自动包含日期目录) $cosKey = $this->generateUniqueKey($fileType, $prefix); // 执行文件上传 $result = $this->cosClient->putObject([ 'Bucket' => $this->bucket, // 存储桶 'Key' => $cosKey, // COS存储路径 'Body' => fopen($tempPath, 'rb'), // 以二进制只读方式打开文件 ]); return [ 'cos_key' => $cosKey, 'full_url' => $this->domain . $cosKey, // 拼接完整访问地址 'location' => $result['Location'] // COS返回的访问地址 ]; } catch (ServiceResponseException $e) { // 记录详细错误日志 Log::error("COS文件上传失败 | {$e->getStatusCode()} | {$e->getErrorCode()} | {$e->getMessage()}"); throw new \Exception('文件上传失败: ' . $e->getMessage()); } } /** * 直接上传二进制内容到COS(适合Base64或内存文件场景) * * @param mixed $content 二进制内容(支持字符串或资源类型) * @param string $filePath 指定在COS中的存储路径(如:images/20230101/abc.jpg) * * @return array [ * 'cos_key' => 'COS存储路径', * 'full_url' => '完整访问URL', * 'location' => 'COS返回的Location' * ] * * @throws \Exception 上传失败时抛出异常 */ public function uploadFile($content, string $filePath): array { try { // 执行二进制内容上传 $result = $this->cosClient->putObject([ 'Bucket' => $this->bucket, // 存储桶 'Key' => $filePath, // 指定存储路径 'Body' => $content, // 直接传入二进制内容 ]); return [ 'cos_key' => $filePath, 'full_url' => $this->domain . $filePath, // 拼接完整访问地址 'location' => $result['Location'] // COS返回的访问地址 ]; } catch (ServiceResponseException $e) { // 记录详细错误日志 Log::error("COS二进制上传失败 | {$e->getStatusCode()} | {$e->getErrorCode()} | {$e->getMessage()}"); throw new \Exception('二进制上传失败: ' . $e->getMessage()); } } /** * 生成唯一存储路径(私有方法) * * 格式:{prefix}/YYYYMMDD/{32位随机字符串}.{ext} * 示例:topic/20230101/7a97e8f7d6e5f4c3b2a1987654321abc.jpg * * @param string $fileType 文件扩展名 * @param string $prefix 路径前缀 * * @return string COS存储路径 */ private function generateUniqueKey(string $fileType, string $prefix): string { $dateSegment = date('Ymd'); // 日期目录 $uniqueName = md5(uniqid(rand(), true)) . '.' . $fileType; // 唯一文件名 return sprintf( '%s/%s/%s', trim($prefix, '/'), // 去除前后斜线 $dateSegment, $uniqueName ); } /** * 获取完整访问URL * * @param string $cosKey COS存储路径 * @return string 完整的HTTP访问地址 */ public function getFullUrl(string $cosKey): string { // 示例:https://cdn.example.com/topic/20230101/abc.jpg return $this->domain . $cosKey; } }