123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- <?php
- // +----------------------------------------------------------------------
- // | Library for ThinkAdmin
- // +----------------------------------------------------------------------
- // | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
- // +----------------------------------------------------------------------
- // | 官方网站: http://demo.thinkadmin.top
- // +----------------------------------------------------------------------
- // | 开源协议 ( https://mit-license.org )
- // +----------------------------------------------------------------------
- // | gitee 仓库地址 :https://gitee.com/zoujingli/ThinkLibrary
- // | github 仓库地址 :https://github.com/zoujingli/ThinkLibrary
- // +----------------------------------------------------------------------
- namespace think\admin\storage;
- use think\admin\extend\HttpExtend;
- use think\admin\Storage;
- /**
- * 七牛云存储支持
- * Class QiniuStorage
- * @package think\admin\storage
- */
- class QiniuStorage extends Storage
- {
- private $bucket;
- private $domain;
- private $accessKey;
- private $secretKey;
- /**
- * 存储引擎初始化
- * @return $this
- * @throws \think\Exception
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- protected function initialize(): Storage
- {
- // 读取配置文件
- $this->bucket = sysconf('storage.qiniu_bucket');
- $this->domain = sysconf('storage.qiniu_http_domain');
- $this->accessKey = sysconf('storage.qiniu_access_key');
- $this->secretKey = sysconf('storage.qiniu_secret_key');
- // 计算链接前缀
- $type = strtolower(sysconf('storage.qiniu_http_protocol'));
- if ($type === 'auto') $this->prefix = "//{$this->domain}/";
- elseif ($type === 'http') $this->prefix = "http://{$this->domain}/";
- elseif ($type === 'https') $this->prefix = "https://{$this->domain}/";
- else throw new \think\Exception('未配置七牛云URL域名哦');
- return $this;
- }
- /**
- * 获取当前实例对象
- * @param null $name
- * @return static
- * @throws \think\Exception
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public static function instance($name = null): Storage
- {
- return parent::instance('qiniu');
- }
- /**
- * 上传文件内容
- * @param string $name 文件名称
- * @param string $file 文件内容
- * @param boolean $safe 安全模式
- * @return array
- * @throws \think\Exception
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function set($name, $file, $safe = false)
- {
- $token = $this->buildUploadToken($name);
- list($attrs, $frontier) = [[], uniqid()];
- foreach (['key' => $name, 'token' => $token, 'fileName' => $name] as $key => $value) {
- $attrs[] = "--{$frontier}";
- $attrs[] = "Content-Disposition:form-data; name=\"{$key}\"";
- $attrs[] = "";
- $attrs[] = $value;
- }
- $attrs[] = "--{$frontier}";
- $attrs[] = "Content-Disposition:form-data; name=\"file\"; filename=\"{$name}\"";
- $attrs[] = "";
- $attrs[] = $file;
- $attrs[] = "--{$frontier}--";
- return json_decode(HttpExtend::post($this->upload(), join("\r\n", $attrs), [
- 'headers' => ["Content-type:multipart/form-data;boundary={$frontier}"],
- ]), true);
- }
- /**
- * 根据文件名读取文件内容
- * @param string $name 文件名称
- * @param boolean $safe 安全模式
- * @return string
- */
- public function get($name, $safe = false)
- {
- $url = $this->url($name, $safe) . "?e=" . time();
- $token = "{$this->accessKey}:{$this->safeBase64(hash_hmac('sha1', $url, $this->secretKey, true))}";
- return file_get_contents("{$url}&token={$token}");
- }
- /**
- * 删除存储的文件
- * @param string $name 文件名称
- * @param boolean $safe 安全模式
- * @return boolean|null
- */
- public function del($name, $safe = false)
- {
- list($EncodedEntryURI, $AccessToken) = $this->getAccessToken($name, 'delete');
- $data = json_decode(HttpExtend::post("http://rs.qiniu.com/delete/{$EncodedEntryURI}", [], [
- 'headers' => ["Authorization:QBox {$AccessToken}"],
- ]), true);
- return empty($data['error']);
- }
- /**
- * 检查文件是否已经存在
- * @param string $name 文件名称
- * @param boolean $safe 安全模式
- * @return boolean
- */
- public function has($name, $safe = false)
- {
- return is_array($this->info($name, $safe));
- }
- /**
- * 获取文件当前URL地址
- * @param string $name 文件名称
- * @param boolean $safe 安全模式
- * @return string
- */
- public function url($name, $safe = false)
- {
- return "{$this->prefix}{$name}";
- }
- /**
- * 获取文件存储路径
- * @param string $name 文件名称
- * @param boolean $safe 安全模式
- * @return string
- */
- public function path($name, $safe = false)
- {
- return $this->url($name, $safe);
- }
- /**
- * 获取文件存储信息
- * @param string $name 文件名称
- * @param boolean $safe 安全模式
- * @return array
- */
- public function info($name, $safe = false)
- {
- list($entry, $token) = $this->getAccessToken($name);
- $data = json_decode(HttpExtend::get("http://rs.qiniu.com/stat/{$entry}", [], ['headers' => ["Authorization: QBox {$token}"]]), true);
- return isset($data['md5']) ? ['file' => $name, 'url' => $this->url($name, $safe), 'hash' => $data['md5'], 'key' => $name] : [];
- }
- /**
- * 获取文件上传地址
- * @return string
- * @throws \think\Exception
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function upload()
- {
- $protocol = $this->app->request->isSsl() ? 'https' : 'http';
- switch (sysconf('storage.qiniu_region')) {
- case '华东':
- return "{$protocol}://up.qiniup.com";
- case '华北':
- return "{$protocol}://up-z1.qiniup.com";
- case '华南':
- return "{$protocol}://up-z2.qiniup.com";
- case '北美':
- return "{$protocol}://up-na0.qiniup.com";
- case '东南亚':
- return "{$protocol}://up-as0.qiniup.com";
- default:
- throw new \think\Exception('未配置七牛云空间区域哦');
- }
- }
- /**
- * 获取文件上传令牌
- * @param string $name 文件名称
- * @param integer $expires 有效时间
- * @return string
- */
- public function buildUploadToken($name = null, $expires = 3600)
- {
- $policy = $this->safeBase64(json_encode([
- "deadline" => time() + $expires, "scope" => is_null($name) ? $this->bucket : "{$this->bucket}:{$name}",
- 'returnBody' => json_encode(['uploaded' => true, 'filename' => '$(key)', 'url' => "{$this->prefix}$(key)"], JSON_UNESCAPED_UNICODE),
- ]));
- return "{$this->accessKey}:{$this->safeBase64(hash_hmac('sha1', $policy, $this->secretKey, true))}:{$policy}";
- }
- /**
- * URL安全的Base64编码
- * @param string $content
- * @return string
- */
- private function safeBase64($content)
- {
- return str_replace(['+', '/'], ['-', '_'], base64_encode($content));
- }
- /**
- * 获取对象管理凭证
- * @param string $name 文件名称
- * @param string $type 操作类型
- * @return array
- */
- private function getAccessToken($name, $type = 'stat')
- {
- $entry = $this->safeBase64("{$this->bucket}:{$name}");
- $sign = hash_hmac('sha1', "/{$type}/{$entry}\n", $this->secretKey, true);
- return [$entry, "{$this->accessKey}:{$this->safeBase64($sign)}"];
- }
- }
|