config['app_id'] = config('tencent.cos.app_id',''); $this->config['secret_id'] = config('tencent.secretId',''); $this->config['secret_key'] = config('tencent.secretKey',''); $this->config['uin'] = config('tencent.cos.uin',''); $this->config['region'] = config('tencent.cos.region',''); $this->config['bucket'] = config('tencent.cos.bucket',''); $this->config['guzzle'] = config('tencent.cos.guzzle',[]); $this->config['signature_expires'] = config('tencent.cos.signature_expires',''); $this->config['base_uri'] = sprintf('https://%s-%s.cos.%s.myqcloud.com/',$this->config['bucket'],$this->config['app_id'],$this->config['region']); } /** * 获取指定目录下的所有对象 * @param Array $result 结果集 * @param String $prefix 列出对象的前缀 * @param String $marker 上次列出对象的断点 * @param Int $maxkeys 设置单次查询打印的最大数量,最大为1000 * @param String $filter_name 搜索文件 */ public function listObjectsAll($prefix='',$filter_name='',$marker='',$maxkeys=16,$delimiter='/',$result=[]){ // 查询条件 $query = []; // 组合条件 if( $marker ) $query['marker'] = $marker; if( $maxkeys ) $query['max-keys'] = $maxkeys; if( $delimiter ) $query['delimiter'] = $delimiter; if( $prefix ) $query['prefix'] = rtrim($prefix,$delimiter).$delimiter; // 增加分隔符后缀,以实现列出当前目录下的对象内容,必须与分割符号配合使用 // 实例化存储桶 $obj = new BucketClient($this->config); // 尝试执行 try { // 查询列表 $objects = $obj->getObjects($query)->toArray(); // 文件夹 $prefixes = isset($objects['ListBucketResult']['CommonPrefixes']) ? $objects['ListBucketResult']['CommonPrefixes'] : []; // 文件 $contents = isset($objects['ListBucketResult']['Contents']) ? $objects['ListBucketResult']['Contents'] : []; // 是否有下一页 $isTruncated = isset($objects['ListBucketResult']['IsTruncated']) ? $objects['ListBucketResult']['IsTruncated'] : 'false'; // 断点 $marker = $isTruncated == 'true' ? $objects['ListBucketResult']['NextMarker'] : ''; /* 是个大坑,如果当前列表只有一个对象时只会返回一维关联数组 */ // 如果存在文件夹,但是文件夹数组中不是以索引数组出现的话 if( $prefixes && empty($prefixes[0]['Prefix']) ) $prefixes = [$prefixes]; // ,但是文件夹数组中不是以索引数组出现的话 if( $contents && empty($contents[0]['Key']) ) $contents = [$contents]; // 获取列表 $objectList = []; // 循环文件夹对象 foreach ( $prefixes as $value ) { // 如果有搜索条件 并且不含有搜索词 if( $filter_name && !stripos( '$'.basename($value['Prefix']), $filter_name) ) continue; // 获取文件key作为路径 array_unshift($objectList,$value['Prefix']); } // 循环文件对象 foreach ( $contents as $value ) { // 如果有搜索条件 并且不含有搜索词 if( $filter_name && !stripos( '$'.basename($value['Key']), $filter_name) ) continue; // 获取文件key作为路径 $objectList[] = $this->config['base_uri'].$value['Key']; } // 合并结果集 $result = array_merge($result,$objectList); // 删除变量,释放内存 unset($objectList,$temp,$prefixes,$contents,$isTruncated); // 如果有断点,继续获取下一批 if( $marker ) $result = $this->listObjectsAll($prefix,$filter_name,$marker,$maxkeys,$delimiter,$result); // 如果有错误返回错误结果 if( isset($result['error'])) return ['error'=>$result['error']]; // 返回结果 return $result; } catch (\Exception $e) { // 如果错误 return ['error'=>$e->getMessage()]; } } /** * 上传对象 * * 将本地的对象(Object)上传至指定存储桶中 * @param String $key 对象键(Key)是对象在存储桶中的唯一标识,亦就是对象在存储桶中的以根起始的完整存储路径 * @param String $body 上传的内容 * @param Array $headers 选项 * * @return String|Array 完整的url访问路径 */ public function upload($key,$body,$headers=[]){ // 避免重复目录路径 $key = ltrim($key,'/'); // 实例化对象管理 $obj = new ObjectClient($this->config); // 尝试执行 try { // 调用上传 $obj->putObject($key,$body,$headers); // 返回结果 return $this->config['base_uri'].$key; } catch (\Exception $e) { // 如果错误 return ['error'=>$e->getMessage()]; } } /** * 删除单个对象 * 在存储桶中删除指定 Object (文件/对象) * @param String $key 对象键(Key)是对象在存储桶中的唯一标识,亦就是对象在存储桶中的以根起始的完整存储路径 * @param String $versionId 删除文件的版本号 * */ public function deleteObject($key,$versionId=null){ // 实例化对象管理 $obj = new ObjectClient($this->config); // 尝试执行 try { // 选择对象,替换掉文件路径 $key = str_ireplace($this->config['base_uri'],'',$key); // 调用上传 $obj->deleteObject($key,$versionId); // 返回结果 return true; } catch (\Exception $e) { // 如果错误 return ['error'=>$e->getMessage()]; } } }