You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

127 lines
3.9 KiB

  1. <?php
  2. namespace Kuxin\Storage;
  3. use Kuxin\Helper\Http;
  4. /**
  5. * 腾讯云云存储
  6. * Class Cos
  7. * @package Kuxin\Storage
  8. * @author Pakey <pakey@qq.com>
  9. */
  10. class Cos
  11. {
  12. public function __construct($config)
  13. {
  14. if (empty($config['key'])) {
  15. trigger_error('access key 未设置');
  16. }
  17. if (empty($config['secret'])) {
  18. trigger_error('access secret 未设置');
  19. }
  20. if (empty($config['bucket'])) {
  21. trigger_error('bucket 未设置');
  22. }
  23. if (empty($config['endpoint'])) {
  24. trigger_error('endpoint 未设置');
  25. }
  26. if (empty($config['url'])) {
  27. trigger_error('访问域名 未设置');
  28. }
  29. $this->accessKeyId = $config['key'];
  30. $this->accessKeySecret = $config['secret'];
  31. $this->bucket = $config['bucket'];
  32. $this->host = $config['bucket'] . '.cos.' . $config['endpoint'];
  33. $this->api = 'http://' . $this->host;
  34. $this->preUrl = $config['url'];
  35. $this->path = '/' . ltrim('/' . $config['path'] ?? '', '/');
  36. }
  37. public function getPath($object)
  38. {
  39. return $object;
  40. }
  41. public function exist($object)
  42. {
  43. $path = $this->path . '/' . $object;
  44. $sign = $this->sign('HEAD', $path, $this->host);
  45. $res = Http::curl($this->api . $path, [], 'HEAD', ['Authorization' => $sign], [CURLOPT_HEADER => 1]);
  46. return strpos($res, ' 200 OK');
  47. }
  48. public function mtime($object)
  49. {
  50. $path = $this->path . '/' . $object;
  51. $sign = $this->sign('HEAD', $path, $this->host);
  52. $res = Http::curl($this->api . $path, [], 'HEAD', ['Authorization' => $sign], [CURLOPT_HEADER => 1]);
  53. $data = Http::parse_headers($res);
  54. return isset($data['last-modified']) ? strtotime($data['last-modified']) : 0;
  55. }
  56. public function read($object)
  57. {
  58. $path = $this->path . '/' . $object;
  59. $sign = $this->sign('GET', $path, $this->host);
  60. $content = Http::curl($this->api . $path, [], 'GET', ['Authorization' => $sign]);
  61. if (strpos($content, '<Error>')) {
  62. return '';
  63. } else {
  64. return $content;
  65. }
  66. }
  67. public function write($object, $content)
  68. {
  69. $path = $this->path . '/' . $object;
  70. $sign = $this->sign('PUT', $path, $this->host);
  71. $res = Http::curl($this->api . $path, $content, 'PUT', ['Authorization' => $sign]);
  72. return $res === "";
  73. }
  74. public function append($object, $content)
  75. {
  76. if ($this->exist($object)) {
  77. $content = $this->read($object) . $content;
  78. }
  79. return $this->write($object, $content);
  80. }
  81. public function remove($object)
  82. {
  83. $path = $this->path . '/' . $object;
  84. $sign = $this->sign('DELETE', $path, $this->host);
  85. $res = Http::curl($this->api . $path, [], 'DELETE', ['Authorization' => $sign]);
  86. return $res === '';
  87. }
  88. public function getUrl($object)
  89. {
  90. return $this->preUrl . $this->path . '/' . $object;
  91. }
  92. public function error()
  93. {
  94. return '';
  95. }
  96. private function sign($method, $path, $host)
  97. {
  98. $signTime = (string)(time() - 60) . ';' . (string)(time() + 3600);
  99. $httpString = strtolower($method) . "\n" . urldecode($path) .
  100. "\n\nhost=" . $host . "\n";
  101. $sha1edHttpString = sha1($httpString);
  102. $stringToSign = "sha1\n$signTime\n$sha1edHttpString\n";
  103. $signKey = hash_hmac('sha1', $signTime, $this->accessKeySecret);
  104. $signature = hash_hmac('sha1', $stringToSign, $signKey);
  105. $authorization = 'q-sign-algorithm=sha1&q-ak=' . $this->accessKeyId .
  106. "&q-sign-time=$signTime&q-key-time=$signTime&q-header-list=host&q-url-param-list=&" .
  107. "q-signature=$signature";
  108. return $authorization;
  109. }
  110. }