Cos.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <?php namespace App\Servers\Tencent;
  2. use Overtrue\CosClient\BucketClient;
  3. use Overtrue\CosClient\ObjectClient;
  4. /**
  5. * 腾讯云Cos
  6. *
  7. */
  8. class Cos{
  9. /* 配置 */
  10. private $config = [];
  11. /**
  12. * 初始化
  13. *
  14. */
  15. public function __construct(){
  16. $this->config['app_id'] = config('tencent.cos.app_id','');
  17. $this->config['secret_id'] = config('tencent.secretId','');
  18. $this->config['secret_key'] = config('tencent.secretKey','');
  19. $this->config['uin'] = config('tencent.cos.uin','');
  20. $this->config['region'] = config('tencent.cos.region','');
  21. $this->config['bucket'] = config('tencent.cos.bucket','');
  22. $this->config['guzzle'] = config('tencent.cos.guzzle',[]);
  23. $this->config['signature_expires'] = config('tencent.cos.signature_expires','');
  24. $this->config['base_uri'] = sprintf('https://%s-%s.cos.%s.myqcloud.com/',$this->config['bucket'],$this->config['app_id'],$this->config['region']);
  25. }
  26. /**
  27. * 获取指定目录下的所有对象
  28. * @param Array $result 结果集
  29. * @param String $prefix 列出对象的前缀
  30. * @param String $marker 上次列出对象的断点
  31. * @param Int $maxkeys 设置单次查询打印的最大数量,最大为1000
  32. * @param String $filter_name 搜索文件
  33. */
  34. public function listObjectsAll($prefix='',$filter_name='',$marker='',$maxkeys=16,$delimiter='/',$result=[]){
  35. // 查询条件
  36. $query = [];
  37. // 组合条件
  38. if( $marker ) $query['marker'] = $marker;
  39. if( $maxkeys ) $query['max-keys'] = $maxkeys;
  40. if( $delimiter ) $query['delimiter'] = $delimiter;
  41. if( $prefix ) $query['prefix'] = rtrim($prefix,$delimiter).$delimiter;
  42. // 增加分隔符后缀,以实现列出当前目录下的对象内容,必须与分割符号配合使用
  43. // 实例化存储桶
  44. $obj = new BucketClient($this->config);
  45. // 尝试执行
  46. try {
  47. // 查询列表
  48. $objects = $obj->getObjects($query)->toArray();
  49. // 文件夹
  50. $prefixes = isset($objects['ListBucketResult']['CommonPrefixes']) ? $objects['ListBucketResult']['CommonPrefixes'] : [];
  51. // 文件
  52. $contents = isset($objects['ListBucketResult']['Contents']) ? $objects['ListBucketResult']['Contents'] : [];
  53. // 是否有下一页
  54. $isTruncated = isset($objects['ListBucketResult']['IsTruncated']) ? $objects['ListBucketResult']['IsTruncated'] : 'false';
  55. // 断点
  56. $marker = $isTruncated == 'true' ? $objects['ListBucketResult']['NextMarker'] : '';
  57. /* 是个大坑,如果当前列表只有一个对象时只会返回一维关联数组 */
  58. // 如果存在文件夹,但是文件夹数组中不是以索引数组出现的话
  59. if( $prefixes && empty($prefixes[0]['Prefix']) ) $prefixes = [$prefixes];
  60. // ,但是文件夹数组中不是以索引数组出现的话
  61. if( $contents && empty($contents[0]['Key']) ) $contents = [$contents];
  62. // 获取列表
  63. $objectList = [];
  64. // 循环文件夹对象
  65. foreach ( $prefixes as $value ) {
  66. // 如果有搜索条件 并且不含有搜索词
  67. if( $filter_name && !stripos( '$'.basename($value['Prefix']), $filter_name) ) continue;
  68. // 获取文件key作为路径
  69. array_unshift($objectList,$value['Prefix']);
  70. }
  71. // 循环文件对象
  72. foreach ( $contents as $value ) {
  73. // 如果有搜索条件 并且不含有搜索词
  74. if( $filter_name && !stripos( '$'.basename($value['Key']), $filter_name) ) continue;
  75. // 获取文件key作为路径
  76. $objectList[] = $this->config['base_uri'].$value['Key'];
  77. }
  78. // 合并结果集
  79. $result = array_merge($result,$objectList);
  80. // 删除变量,释放内存
  81. unset($objectList,$temp,$prefixes,$contents,$isTruncated);
  82. // 如果有断点,继续获取下一批
  83. if( $marker ) $result = $this->listObjectsAll($prefix,$filter_name,$marker,$maxkeys,$delimiter,$result);
  84. // 如果有错误返回错误结果
  85. if( isset($result['error'])) return ['error'=>$result['error']];
  86. // 返回结果
  87. return $result;
  88. } catch (\Exception $e) {
  89. // 如果错误
  90. return ['error'=>$e->getMessage()];
  91. }
  92. }
  93. /**
  94. * 上传对象
  95. *
  96. * 将本地的对象(Object)上传至指定存储桶中
  97. * @param String $key 对象键(Key)是对象在存储桶中的唯一标识,亦就是对象在存储桶中的以根起始的完整存储路径
  98. * @param String $body 上传的内容
  99. * @param Array $headers 选项
  100. *
  101. * @return String|Array 完整的url访问路径
  102. */
  103. public function upload($key,$body,$headers=[]){
  104. // 避免重复目录路径
  105. $key = ltrim($key,'/');
  106. // 实例化对象管理
  107. $obj = new ObjectClient($this->config);
  108. // 尝试执行
  109. try {
  110. // 调用上传
  111. $obj->putObject($key,$body,$headers);
  112. // 返回结果
  113. return $this->config['base_uri'].$key;
  114. } catch (\Exception $e) {
  115. // 如果错误
  116. return ['error'=>$e->getMessage()];
  117. }
  118. }
  119. /**
  120. * 删除单个对象
  121. * 在存储桶中删除指定 Object (文件/对象)
  122. * @param String $key 对象键(Key)是对象在存储桶中的唯一标识,亦就是对象在存储桶中的以根起始的完整存储路径
  123. * @param String $versionId 删除文件的版本号
  124. *
  125. */
  126. public function deleteObject($key,$versionId=null){
  127. // 实例化对象管理
  128. $obj = new ObjectClient($this->config);
  129. // 尝试执行
  130. try {
  131. // 选择对象,替换掉文件路径
  132. $key = str_ireplace($this->config['base_uri'],'',$key);
  133. // 调用上传
  134. $obj->deleteObject($key,$versionId);
  135. // 返回结果
  136. return true;
  137. } catch (\Exception $e) {
  138. // 如果错误
  139. return ['error'=>$e->getMessage()];
  140. }
  141. }
  142. }