Showing
16 changed files
with
2149 additions
and
0 deletions
vendor/Qiniu/examples/upload_tokens.php
0 → 100755
| 1 | +<?php | ||
| 2 | +require_once __DIR__ . '/../autoload.php'; | ||
| 3 | + | ||
| 4 | +use \Qiniu\Auth; | ||
| 5 | + | ||
| 6 | +$accessKey = getenv('QINIU_ACCESS_KEY'); | ||
| 7 | +$secretKey = getenv('QINIU_SECRET_KEY'); | ||
| 8 | +$bucket = getenv('QINIU_TEST_BUCKET'); | ||
| 9 | + | ||
| 10 | +// 初始化Auth状态 | ||
| 11 | +$auth = new Auth($accessKey, $secretKey); | ||
| 12 | + | ||
| 13 | +// 简单上传凭证 | ||
| 14 | +$expires = 3600; | ||
| 15 | + | ||
| 16 | +$policy = null; | ||
| 17 | +$upToken = $auth->uploadToken($bucket, null, $expires, $policy, true); | ||
| 18 | +print($upToken . "\n"); | ||
| 19 | + | ||
| 20 | +// 自定义凭证有效期(示例2小时) | ||
| 21 | +$expires = 7200; | ||
| 22 | +$upToken = $auth->uploadToken($bucket, null, $expires, $policy, true); | ||
| 23 | +print($upToken . "\n"); | ||
| 24 | + | ||
| 25 | +// 覆盖上传凭证 | ||
| 26 | +$expires = 3600; | ||
| 27 | +$keyToOverwrite = 'qiniu.mp4'; | ||
| 28 | +$upToken = $auth->uploadToken($bucket, $keyToOverwrite, $expires, $policy, true); | ||
| 29 | +print($upToken . "\n"); | ||
| 30 | + | ||
| 31 | +//自定义上传回复(非callback模式)凭证 | ||
| 32 | +$returnBody = '{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}'; | ||
| 33 | +$policy = array( | ||
| 34 | + 'returnBody' => $returnBody | ||
| 35 | +); | ||
| 36 | +$upToken = $auth->uploadToken($bucket, null, $expires, $policy, true); | ||
| 37 | +print($upToken . "\n"); | ||
| 38 | + | ||
| 39 | +//带回调业务服务器的凭证(application/json) | ||
| 40 | +$policy = array( | ||
| 41 | + 'callbackUrl' => 'http://api.example.com/qiniu/upload/callback', | ||
| 42 | + 'callbackBody' => '{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}', | ||
| 43 | + 'callbackBodyType' => 'application/json' | ||
| 44 | +); | ||
| 45 | +$upToken = $auth->uploadToken($bucket, null, $expires, $policy, true); | ||
| 46 | +print($upToken . "\n"); | ||
| 47 | + | ||
| 48 | + | ||
| 49 | +//带回调业务服务器的凭证(application/x-www-form-urlencoded) | ||
| 50 | +$policy = array( | ||
| 51 | + 'callbackUrl' => 'http://api.example.com/qiniu/upload/callback', | ||
| 52 | + 'callbackBody' => 'key=$(key)&hash=$(etag)&bucket=$(bucket)&fsize=$(fsize)&name=$(x:name)' | ||
| 53 | +); | ||
| 54 | +$upToken = $auth->uploadToken($bucket, null, $expires, $policy, true); | ||
| 55 | +print($upToken . "\n"); | ||
| 56 | + | ||
| 57 | +//带数据处理的凭证 | ||
| 58 | +$saveMp4Entry = \Qiniu\base64_urlSafeEncode($bucket . ":avthumb_test_target.mp4"); | ||
| 59 | +$saveJpgEntry = \Qiniu\base64_urlSafeEncode($bucket . ":vframe_test_target.jpg"); | ||
| 60 | +$avthumbMp4Fop = "avthumb/mp4|saveas/" . $saveMp4Entry; | ||
| 61 | +$vframeJpgFop = "vframe/jpg/offset/1|saveas/" . $saveJpgEntry; | ||
| 62 | +$policy = array( | ||
| 63 | + 'persistentOps' => $avthumbMp4Fop . ";" . $vframeJpgFop, | ||
| 64 | + 'persistentPipeline' => "video-pipe", | ||
| 65 | + 'persistentNotifyUrl' => "http://api.example.com/qiniu/pfop/notify", | ||
| 66 | +); | ||
| 67 | +$upToken = $auth->uploadToken($bucket, null, $expires, $policy, true); | ||
| 68 | +print($upToken . "\n"); |
| 1 | +<?php | ||
| 2 | +require_once __DIR__ . '/../autoload.php'; | ||
| 3 | + | ||
| 4 | +use Qiniu\Auth; | ||
| 5 | + | ||
| 6 | +$accessKey = getenv('QINIU_ACCESS_KEY'); | ||
| 7 | +$secretKey = getenv('QINIU_SECRET_KEY'); | ||
| 8 | +$bucket = getenv('QINIU_TEST_BUCKET'); | ||
| 9 | + | ||
| 10 | +$auth = new Auth($accessKey, $secretKey); | ||
| 11 | + | ||
| 12 | +//获取回调的body信息 | ||
| 13 | +$callbackBody = file_get_contents('php://input'); | ||
| 14 | + | ||
| 15 | +//回调的contentType | ||
| 16 | +$contentType = 'application/x-www-form-urlencoded'; | ||
| 17 | + | ||
| 18 | +//回调的签名信息,可以验证该回调是否来自七牛 | ||
| 19 | +$authorization = $_SERVER['HTTP_AUTHORIZATION']; | ||
| 20 | + | ||
| 21 | +//七牛回调的url,具体可以参考:http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html | ||
| 22 | +$url = 'http://172.30.251.210/upload_verify_callback.php'; | ||
| 23 | + | ||
| 24 | +$isQiniuCallback = $auth->verifyCallback($contentType, $authorization, $url, $callbackBody); | ||
| 25 | + | ||
| 26 | +if ($isQiniuCallback) { | ||
| 27 | + $resp = array('ret' => 'success'); | ||
| 28 | +} else { | ||
| 29 | + $resp = array('ret' => 'failed'); | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | +echo json_encode($resp); |
vendor/Qiniu/src/Qiniu/Auth.php
0 → 100755
| 1 | +<?php | ||
| 2 | +namespace Qiniu; | ||
| 3 | + | ||
| 4 | +use Qiniu\Zone; | ||
| 5 | + | ||
| 6 | +final class Auth | ||
| 7 | +{ | ||
| 8 | + private $accessKey; | ||
| 9 | + private $secretKey; | ||
| 10 | + | ||
| 11 | + public function __construct($accessKey, $secretKey) | ||
| 12 | + { | ||
| 13 | + $this->accessKey = $accessKey; | ||
| 14 | + $this->secretKey = $secretKey; | ||
| 15 | + } | ||
| 16 | + | ||
| 17 | + public function getAccessKey() | ||
| 18 | + { | ||
| 19 | + return $this->accessKey; | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + public function sign($data) | ||
| 23 | + { | ||
| 24 | + $hmac = hash_hmac('sha1', $data, $this->secretKey, true); | ||
| 25 | + return $this->accessKey . ':' . \Qiniu\base64_urlSafeEncode($hmac); | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + public function signWithData($data) | ||
| 29 | + { | ||
| 30 | + $encodedData = \Qiniu\base64_urlSafeEncode($data); | ||
| 31 | + return $this->sign($encodedData) . ':' . $encodedData; | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + public function signRequest($urlString, $body, $contentType = null) | ||
| 35 | + { | ||
| 36 | + $url = parse_url($urlString); | ||
| 37 | + $data = ''; | ||
| 38 | + if (array_key_exists('path', $url)) { | ||
| 39 | + $data = $url['path']; | ||
| 40 | + } | ||
| 41 | + if (array_key_exists('query', $url)) { | ||
| 42 | + $data .= '?' . $url['query']; | ||
| 43 | + } | ||
| 44 | + $data .= "\n"; | ||
| 45 | + | ||
| 46 | + if ($body !== null && $contentType === 'application/x-www-form-urlencoded') { | ||
| 47 | + $data .= $body; | ||
| 48 | + } | ||
| 49 | + return $this->sign($data); | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + public function verifyCallback($contentType, $originAuthorization, $url, $body) | ||
| 53 | + { | ||
| 54 | + $authorization = 'QBox ' . $this->signRequest($url, $body, $contentType); | ||
| 55 | + return $originAuthorization === $authorization; | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + public function privateDownloadUrl($baseUrl, $expires = 3600) | ||
| 59 | + { | ||
| 60 | + $deadline = time() + $expires; | ||
| 61 | + | ||
| 62 | + $pos = strpos($baseUrl, '?'); | ||
| 63 | + if ($pos !== false) { | ||
| 64 | + $baseUrl .= '&e='; | ||
| 65 | + } else { | ||
| 66 | + $baseUrl .= '?e='; | ||
| 67 | + } | ||
| 68 | + $baseUrl .= $deadline; | ||
| 69 | + | ||
| 70 | + $token = $this->sign($baseUrl); | ||
| 71 | + return "$baseUrl&token=$token"; | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + public function uploadToken($bucket, $key = null, $expires = 3600, $policy = null, $strictPolicy = true) | ||
| 75 | + { | ||
| 76 | + $deadline = time() + $expires; | ||
| 77 | + $scope = $bucket; | ||
| 78 | + if ($key !== null) { | ||
| 79 | + $scope .= ':' . $key; | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + $args = self::copyPolicy($args, $policy, $strictPolicy); | ||
| 83 | + $args['scope'] = $scope; | ||
| 84 | + $args['deadline'] = $deadline; | ||
| 85 | + | ||
| 86 | + $b = json_encode($args); | ||
| 87 | + return $this->signWithData($b); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + /** | ||
| 91 | + *上传策略,参数规格详见 | ||
| 92 | + *http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html | ||
| 93 | + */ | ||
| 94 | + private static $policyFields = array( | ||
| 95 | + 'callbackUrl', | ||
| 96 | + 'callbackBody', | ||
| 97 | + 'callbackHost', | ||
| 98 | + 'callbackBodyType', | ||
| 99 | + 'callbackFetchKey', | ||
| 100 | + | ||
| 101 | + 'returnUrl', | ||
| 102 | + 'returnBody', | ||
| 103 | + | ||
| 104 | + 'endUser', | ||
| 105 | + 'saveKey', | ||
| 106 | + 'insertOnly', | ||
| 107 | + | ||
| 108 | + 'detectMime', | ||
| 109 | + 'mimeLimit', | ||
| 110 | + 'fsizeMin', | ||
| 111 | + 'fsizeLimit', | ||
| 112 | + | ||
| 113 | + 'persistentOps', | ||
| 114 | + 'persistentNotifyUrl', | ||
| 115 | + 'persistentPipeline', | ||
| 116 | + | ||
| 117 | + 'deleteAfterDays', | ||
| 118 | + 'fileType', | ||
| 119 | + 'isPrefixalScope', | ||
| 120 | + ); | ||
| 121 | + | ||
| 122 | + private static function copyPolicy(&$policy, $originPolicy, $strictPolicy) | ||
| 123 | + { | ||
| 124 | + if ($originPolicy === null) { | ||
| 125 | + return array(); | ||
| 126 | + } | ||
| 127 | + foreach ($originPolicy as $key => $value) { | ||
| 128 | + if (!$strictPolicy || in_array((string)$key, self::$policyFields, true)) { | ||
| 129 | + $policy[$key] = $value; | ||
| 130 | + } | ||
| 131 | + } | ||
| 132 | + return $policy; | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + public function authorization($url, $body = null, $contentType = null) | ||
| 136 | + { | ||
| 137 | + $authorization = 'QBox ' . $this->signRequest($url, $body, $contentType); | ||
| 138 | + return array('Authorization' => $authorization); | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + public function authorizationV2($url, $method, $body = null, $contentType = null) | ||
| 142 | + { | ||
| 143 | + $urlItems = parse_url($url); | ||
| 144 | + $host = $urlItems['host']; | ||
| 145 | + | ||
| 146 | + if (isset($urlItems['port'])) { | ||
| 147 | + $port = $urlItems['port']; | ||
| 148 | + } else { | ||
| 149 | + $port = ''; | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + $path = $urlItems['path']; | ||
| 153 | + if (isset($urlItems['query'])) { | ||
| 154 | + $query = $urlItems['query']; | ||
| 155 | + } else { | ||
| 156 | + $query = ''; | ||
| 157 | + } | ||
| 158 | + | ||
| 159 | + //write request uri | ||
| 160 | + $toSignStr = $method . ' ' . $path; | ||
| 161 | + if (!empty($query)) { | ||
| 162 | + $toSignStr .= '?' . $query; | ||
| 163 | + } | ||
| 164 | + | ||
| 165 | + //write host and port | ||
| 166 | + $toSignStr .= "\nHost: " . $host; | ||
| 167 | + if (!empty($port)) { | ||
| 168 | + $toSignStr .= ":" . $port; | ||
| 169 | + } | ||
| 170 | + | ||
| 171 | + //write content type | ||
| 172 | + if (!empty($contentType)) { | ||
| 173 | + $toSignStr .= "\nContent-Type: " . $contentType; | ||
| 174 | + } | ||
| 175 | + | ||
| 176 | + $toSignStr .= "\n\n"; | ||
| 177 | + | ||
| 178 | + //write body | ||
| 179 | + if (!empty($body)) { | ||
| 180 | + $toSignStr .= $body; | ||
| 181 | + } | ||
| 182 | + | ||
| 183 | + $sign = $this->sign($toSignStr); | ||
| 184 | + $auth = 'Qiniu ' . $sign; | ||
| 185 | + return array('Authorization' => $auth); | ||
| 186 | + } | ||
| 187 | +} |
vendor/Qiniu/src/Qiniu/Cdn/CdnManager.php
0 → 100755
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace Qiniu\Cdn; | ||
| 4 | + | ||
| 5 | +use Qiniu\Auth; | ||
| 6 | +use Qiniu\Http\Error; | ||
| 7 | +use Qiniu\Http\Client; | ||
| 8 | + | ||
| 9 | +final class CdnManager | ||
| 10 | +{ | ||
| 11 | + | ||
| 12 | + private $auth; | ||
| 13 | + private $server; | ||
| 14 | + | ||
| 15 | + public function __construct(Auth $auth) | ||
| 16 | + { | ||
| 17 | + $this->auth = $auth; | ||
| 18 | + $this->server = 'http://fusion.qiniuapi.com'; | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + /** | ||
| 22 | + * @param array $urls 待刷新的文件链接数组 | ||
| 23 | + * @return array | ||
| 24 | + */ | ||
| 25 | + public function refreshUrls(array $urls) | ||
| 26 | + { | ||
| 27 | + return $this->refreshUrlsAndDirs($urls, array()); | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * @param array $dirs 待刷新的文件链接数组 | ||
| 32 | + * @return array | ||
| 33 | + * 目前客户默认没有目录刷新权限,刷新会有400038报错,参考:https://developer.qiniu.com/fusion/api/1229/cache-refresh | ||
| 34 | + * 需要刷新目录请工单联系技术支持 https://support.qiniu.com/tickets/category | ||
| 35 | + */ | ||
| 36 | + public function refreshDirs(array $dirs) | ||
| 37 | + { | ||
| 38 | + return $this->refreshUrlsAndDirs(array(), $dirs); | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + /** | ||
| 42 | + * @param array $urls 待刷新的文件链接数组 | ||
| 43 | + * @param array $dirs 待刷新的目录链接数组 | ||
| 44 | + * | ||
| 45 | + * @return array 刷新的请求回复和错误,参考 examples/cdn_manager.php 代码 | ||
| 46 | + * @link http://developer.qiniu.com/article/fusion/api/refresh.html | ||
| 47 | + * | ||
| 48 | + * 目前客户默认没有目录刷新权限,刷新会有400038报错,参考:https://developer.qiniu.com/fusion/api/1229/cache-refresh | ||
| 49 | + * 需要刷新目录请工单联系技术支持 https://support.qiniu.com/tickets/category | ||
| 50 | + */ | ||
| 51 | + public function refreshUrlsAndDirs(array $urls, array $dirs) | ||
| 52 | + { | ||
| 53 | + $req = array(); | ||
| 54 | + if (!empty($urls)) { | ||
| 55 | + $req['urls'] = $urls; | ||
| 56 | + } | ||
| 57 | + if (!empty($dirs)) { | ||
| 58 | + $req['dirs'] = $dirs; | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + $url = $this->server . '/v2/tune/refresh'; | ||
| 62 | + $body = json_encode($req); | ||
| 63 | + return $this->post($url, $body); | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + /** | ||
| 67 | + * @param array $urls 待预取的文件链接数组 | ||
| 68 | + * | ||
| 69 | + * @return array 预取的请求回复和错误,参考 examples/cdn_manager.php 代码 | ||
| 70 | + * | ||
| 71 | + * @link http://developer.qiniu.com/article/fusion/api/refresh.html | ||
| 72 | + */ | ||
| 73 | + public function prefetchUrls(array $urls) | ||
| 74 | + { | ||
| 75 | + $req = array( | ||
| 76 | + 'urls' => $urls, | ||
| 77 | + ); | ||
| 78 | + | ||
| 79 | + $url = $this->server . '/v2/tune/prefetch'; | ||
| 80 | + $body = json_encode($req); | ||
| 81 | + return $this->post($url, $body); | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + /** | ||
| 85 | + * @param array $domains 待获取带宽数据的域名数组 | ||
| 86 | + * @param string $startDate 开始的日期,格式类似 2017-01-01 | ||
| 87 | + * @param string $endDate 结束的日期,格式类似 2017-01-01 | ||
| 88 | + * @param string $granularity 获取数据的时间间隔,可以是 5min, hour 或者 day | ||
| 89 | + * | ||
| 90 | + * @return array 带宽数据和错误信息,参考 examples/cdn_manager.php 代码 | ||
| 91 | + * | ||
| 92 | + * @link http://developer.qiniu.com/article/fusion/api/traffic-bandwidth.html | ||
| 93 | + */ | ||
| 94 | + public function getBandwidthData(array $domains, $startDate, $endDate, $granularity) | ||
| 95 | + { | ||
| 96 | + $req = array(); | ||
| 97 | + $req['domains'] = implode(';', $domains); | ||
| 98 | + $req['startDate'] = $startDate; | ||
| 99 | + $req['endDate'] = $endDate; | ||
| 100 | + $req['granularity'] = $granularity; | ||
| 101 | + | ||
| 102 | + $url = $this->server . '/v2/tune/bandwidth'; | ||
| 103 | + $body = json_encode($req); | ||
| 104 | + return $this->post($url, $body); | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + /** | ||
| 108 | + * @param array $domains 待获取流量数据的域名数组 | ||
| 109 | + * @param string $startDate 开始的日期,格式类似 2017-01-01 | ||
| 110 | + * @param string $endDate 结束的日期,格式类似 2017-01-01 | ||
| 111 | + * @param string $granularity 获取数据的时间间隔,可以是 5min, hour 或者 day | ||
| 112 | + * | ||
| 113 | + * @return array 流量数据和错误信息,参考 examples/cdn_manager.php 代码 | ||
| 114 | + * | ||
| 115 | + * @link http://developer.qiniu.com/article/fusion/api/traffic-bandwidth.html | ||
| 116 | + */ | ||
| 117 | + public function getFluxData(array $domains, $startDate, $endDate, $granularity) | ||
| 118 | + { | ||
| 119 | + $req = array(); | ||
| 120 | + $req['domains'] = implode(';', $domains); | ||
| 121 | + $req['startDate'] = $startDate; | ||
| 122 | + $req['endDate'] = $endDate; | ||
| 123 | + $req['granularity'] = $granularity; | ||
| 124 | + | ||
| 125 | + $url = $this->server . '/v2/tune/flux'; | ||
| 126 | + $body = json_encode($req); | ||
| 127 | + return $this->post($url, $body); | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + /** | ||
| 131 | + * @param array $domains 待获取日志下载链接的域名数组 | ||
| 132 | + * @param string $logDate 获取指定日期的日志下载链接,格式类似 2017-01-01 | ||
| 133 | + * | ||
| 134 | + * @return array 日志下载链接数据和错误信息,参考 examples/cdn_manager.php 代码 | ||
| 135 | + * | ||
| 136 | + * @link http://developer.qiniu.com/article/fusion/api/log.html | ||
| 137 | + */ | ||
| 138 | + public function getCdnLogList(array $domains, $logDate) | ||
| 139 | + { | ||
| 140 | + $req = array(); | ||
| 141 | + $req['domains'] = implode(';', $domains); | ||
| 142 | + $req['day'] = $logDate; | ||
| 143 | + | ||
| 144 | + $url = $this->server . '/v2/tune/log/list'; | ||
| 145 | + $body = json_encode($req); | ||
| 146 | + return $this->post($url, $body); | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + private function post($url, $body) | ||
| 150 | + { | ||
| 151 | + $headers = $this->auth->authorization($url, $body, 'application/json'); | ||
| 152 | + $headers['Content-Type'] = 'application/json'; | ||
| 153 | + $ret = Client::post($url, $body, $headers); | ||
| 154 | + if (!$ret->ok()) { | ||
| 155 | + return array(null, new Error($url, $ret)); | ||
| 156 | + } | ||
| 157 | + $r = ($ret->body === null) ? array() : $ret->json(); | ||
| 158 | + return array($r, null); | ||
| 159 | + } | ||
| 160 | + | ||
| 161 | + /** | ||
| 162 | + * 构建时间戳防盗链鉴权的访问外链 | ||
| 163 | + * | ||
| 164 | + * @param string $rawUrl 需要签名的资源url | ||
| 165 | + * @param string $encryptKey 时间戳防盗链密钥 | ||
| 166 | + * @param string $durationInSeconds 链接的有效期(以秒为单位) | ||
| 167 | + * | ||
| 168 | + * @return string 带鉴权信息的资源外链,参考 examples/cdn_timestamp_antileech.php 代码 | ||
| 169 | + */ | ||
| 170 | + public static function createTimestampAntiLeechUrl($rawUrl, $encryptKey, $durationInSeconds) | ||
| 171 | + { | ||
| 172 | + | ||
| 173 | + $parsedUrl = parse_url($rawUrl); | ||
| 174 | + | ||
| 175 | + $deadline = time() + $durationInSeconds; | ||
| 176 | + $expireHex = dechex($deadline); | ||
| 177 | + $path = isset($parsedUrl['path']) ? $parsedUrl['path'] : ''; | ||
| 178 | + | ||
| 179 | + $strToSign = $encryptKey . $path . $expireHex; | ||
| 180 | + $signStr = md5($strToSign); | ||
| 181 | + | ||
| 182 | + if (isset($parsedUrl['query'])) { | ||
| 183 | + $signedUrl = $rawUrl . '&sign=' . $signStr . '&t=' . $expireHex; | ||
| 184 | + } else { | ||
| 185 | + $signedUrl = $rawUrl . '?sign=' . $signStr . '&t=' . $expireHex; | ||
| 186 | + } | ||
| 187 | + | ||
| 188 | + return $signedUrl; | ||
| 189 | + } | ||
| 190 | +} |
vendor/Qiniu/src/Qiniu/Config.php
0 → 100755
| 1 | +<?php | ||
| 2 | +namespace Qiniu; | ||
| 3 | + | ||
| 4 | +final class Config | ||
| 5 | +{ | ||
| 6 | + const SDK_VER = '7.2.5'; | ||
| 7 | + | ||
| 8 | + const BLOCK_SIZE = 4194304; //4*1024*1024 分块上传块大小,该参数为接口规格,不能修改 | ||
| 9 | + | ||
| 10 | + const RSF_HOST = 'rsf.qiniu.com'; | ||
| 11 | + const API_HOST = 'api.qiniu.com'; | ||
| 12 | + const RS_HOST = 'rs.qiniu.com'; //RS Host | ||
| 13 | + const UC_HOST = 'https://api.qiniu.com'; //UC Host | ||
| 14 | + const RTCAPI_HOST = 'http://rtc.qiniuapi.com'; | ||
| 15 | + const RTCAPI_VERSION = 'v3'; | ||
| 16 | + | ||
| 17 | + // Zone 空间对应的机房 | ||
| 18 | + public $zone; | ||
| 19 | + //BOOL 是否使用https域名 | ||
| 20 | + public $useHTTPS; | ||
| 21 | + //BOOL 是否使用CDN加速上传域名 | ||
| 22 | + public $useCdnDomains; | ||
| 23 | + // Zone Cache | ||
| 24 | + private $zoneCache; | ||
| 25 | + | ||
| 26 | + // 构造函数 | ||
| 27 | + public function __construct(Zone $z = null) | ||
| 28 | + { | ||
| 29 | + $this->zone = $z; | ||
| 30 | + $this->useHTTPS = false; | ||
| 31 | + $this->useCdnDomains = false; | ||
| 32 | + $this->zoneCache = array(); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + public function getUpHost($accessKey, $bucket) | ||
| 36 | + { | ||
| 37 | + $zone = $this->getZone($accessKey, $bucket); | ||
| 38 | + if ($this->useHTTPS === true) { | ||
| 39 | + $scheme = "https://"; | ||
| 40 | + } else { | ||
| 41 | + $scheme = "http://"; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + $host = $zone->srcUpHosts[0]; | ||
| 45 | + if ($this->useCdnDomains === true) { | ||
| 46 | + $host = $zone->cdnUpHosts[0]; | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + return $scheme . $host; | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + public function getUpBackupHost($accessKey, $bucket) | ||
| 53 | + { | ||
| 54 | + $zone = $this->getZone($accessKey, $bucket); | ||
| 55 | + if ($this->useHTTPS === true) { | ||
| 56 | + $scheme = "https://"; | ||
| 57 | + } else { | ||
| 58 | + $scheme = "http://"; | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + $host = $zone->cdnUpHosts[0]; | ||
| 62 | + if ($this->useCdnDomains === true) { | ||
| 63 | + $host = $zone->srcUpHosts[0]; | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + return $scheme . $host; | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + public function getRsHost($accessKey, $bucket) | ||
| 70 | + { | ||
| 71 | + $zone = $this->getZone($accessKey, $bucket); | ||
| 72 | + | ||
| 73 | + if ($this->useHTTPS === true) { | ||
| 74 | + $scheme = "https://"; | ||
| 75 | + } else { | ||
| 76 | + $scheme = "http://"; | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + return $scheme . $zone->rsHost; | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + public function getRsfHost($accessKey, $bucket) | ||
| 83 | + { | ||
| 84 | + $zone = $this->getZone($accessKey, $bucket); | ||
| 85 | + | ||
| 86 | + if ($this->useHTTPS === true) { | ||
| 87 | + $scheme = "https://"; | ||
| 88 | + } else { | ||
| 89 | + $scheme = "http://"; | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + return $scheme . $zone->rsfHost; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + public function getIovipHost($accessKey, $bucket) | ||
| 96 | + { | ||
| 97 | + $zone = $this->getZone($accessKey, $bucket); | ||
| 98 | + | ||
| 99 | + if ($this->useHTTPS === true) { | ||
| 100 | + $scheme = "https://"; | ||
| 101 | + } else { | ||
| 102 | + $scheme = "http://"; | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + return $scheme . $zone->iovipHost; | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + public function getApiHost($accessKey, $bucket) | ||
| 109 | + { | ||
| 110 | + $zone = $this->getZone($accessKey, $bucket); | ||
| 111 | + | ||
| 112 | + if ($this->useHTTPS === true) { | ||
| 113 | + $scheme = "https://"; | ||
| 114 | + } else { | ||
| 115 | + $scheme = "http://"; | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + return $scheme . $zone->apiHost; | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + private function getZone($accessKey, $bucket) | ||
| 122 | + { | ||
| 123 | + $cacheId = "$accessKey:$bucket"; | ||
| 124 | + | ||
| 125 | + if (isset($this->zoneCache[$cacheId])) { | ||
| 126 | + $zone = $this->zoneCache[$cacheId]; | ||
| 127 | + } elseif (isset($this->zone)) { | ||
| 128 | + $zone = $this->zone; | ||
| 129 | + $this->zoneCache[$cacheId] = $zone; | ||
| 130 | + } else { | ||
| 131 | + $zone = Zone::queryZone($accessKey, $bucket); | ||
| 132 | + $this->zoneCache[$cacheId] = $zone; | ||
| 133 | + } | ||
| 134 | + return $zone; | ||
| 135 | + } | ||
| 136 | +} |
vendor/Qiniu/src/Qiniu/Etag.php
0 → 100755
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace Qiniu; | ||
| 4 | + | ||
| 5 | +use Qiniu\Config; | ||
| 6 | + | ||
| 7 | +final class Etag | ||
| 8 | +{ | ||
| 9 | + private static function packArray($v, $a) | ||
| 10 | + { | ||
| 11 | + return call_user_func_array('pack', array_merge(array($v), (array)$a)); | ||
| 12 | + } | ||
| 13 | + | ||
| 14 | + private static function blockCount($fsize) | ||
| 15 | + { | ||
| 16 | + return intval(($fsize + (Config::BLOCK_SIZE - 1)) / Config::BLOCK_SIZE); | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + private static function calcSha1($data) | ||
| 20 | + { | ||
| 21 | + $sha1Str = sha1($data, true); | ||
| 22 | + $err = error_get_last(); | ||
| 23 | + if ($err !== null) { | ||
| 24 | + return array(null, $err); | ||
| 25 | + } | ||
| 26 | + $byteArray = unpack('C*', $sha1Str); | ||
| 27 | + return array($byteArray, null); | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + | ||
| 31 | + public static function sum($filename) | ||
| 32 | + { | ||
| 33 | + $fhandler = fopen($filename, 'r'); | ||
| 34 | + $err = error_get_last(); | ||
| 35 | + if ($err !== null) { | ||
| 36 | + return array(null, $err); | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + $fstat = fstat($fhandler); | ||
| 40 | + $fsize = $fstat['size']; | ||
| 41 | + if ((int)$fsize === 0) { | ||
| 42 | + fclose($fhandler); | ||
| 43 | + return array('Fto5o-5ea0sNMlW_75VgGJCv2AcJ', null); | ||
| 44 | + } | ||
| 45 | + $blockCnt = self::blockCount($fsize); | ||
| 46 | + $sha1Buf = array(); | ||
| 47 | + | ||
| 48 | + if ($blockCnt <= 1) { | ||
| 49 | + array_push($sha1Buf, 0x16); | ||
| 50 | + $fdata = fread($fhandler, Config::BLOCK_SIZE); | ||
| 51 | + if ($err !== null) { | ||
| 52 | + fclose($fhandler); | ||
| 53 | + return array(null, $err); | ||
| 54 | + } | ||
| 55 | + list($sha1Code,) = self::calcSha1($fdata); | ||
| 56 | + $sha1Buf = array_merge($sha1Buf, $sha1Code); | ||
| 57 | + } else { | ||
| 58 | + array_push($sha1Buf, 0x96); | ||
| 59 | + $sha1BlockBuf = array(); | ||
| 60 | + for ($i = 0; $i < $blockCnt; $i++) { | ||
| 61 | + $fdata = fread($fhandler, Config::BLOCK_SIZE); | ||
| 62 | + list($sha1Code, $err) = self::calcSha1($fdata); | ||
| 63 | + if ($err !== null) { | ||
| 64 | + fclose($fhandler); | ||
| 65 | + return array(null, $err); | ||
| 66 | + } | ||
| 67 | + $sha1BlockBuf = array_merge($sha1BlockBuf, $sha1Code); | ||
| 68 | + } | ||
| 69 | + $tmpData = self::packArray('C*', $sha1BlockBuf); | ||
| 70 | + list($sha1Final,) = self::calcSha1($tmpData); | ||
| 71 | + $sha1Buf = array_merge($sha1Buf, $sha1Final); | ||
| 72 | + } | ||
| 73 | + $etag = \Qiniu\base64_urlSafeEncode(self::packArray('C*', $sha1Buf)); | ||
| 74 | + return array($etag, null); | ||
| 75 | + } | ||
| 76 | +} |
vendor/Qiniu/src/Qiniu/Http/Client.php
0 → 100755
| 1 | +<?php | ||
| 2 | +namespace Qiniu\Http; | ||
| 3 | + | ||
| 4 | +use Qiniu\Config; | ||
| 5 | +use Qiniu\Http\Request; | ||
| 6 | +use Qiniu\Http\Response; | ||
| 7 | + | ||
| 8 | +final class Client | ||
| 9 | +{ | ||
| 10 | + public static function get($url, array $headers = array()) | ||
| 11 | + { | ||
| 12 | + $request = new Request('GET', $url, $headers); | ||
| 13 | + return self::sendRequest($request); | ||
| 14 | + } | ||
| 15 | + | ||
| 16 | + public static function delete($url, array $headers = array()) | ||
| 17 | + { | ||
| 18 | + $request = new Request('DELETE', $url, $headers); | ||
| 19 | + return self::sendRequest($request); | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + public static function post($url, $body, array $headers = array()) | ||
| 23 | + { | ||
| 24 | + $request = new Request('POST', $url, $headers, $body); | ||
| 25 | + return self::sendRequest($request); | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + public static function multipartPost( | ||
| 29 | + $url, | ||
| 30 | + $fields, | ||
| 31 | + $name, | ||
| 32 | + $fileName, | ||
| 33 | + $fileBody, | ||
| 34 | + $mimeType = null, | ||
| 35 | + array $headers = array() | ||
| 36 | + ) { | ||
| 37 | + $data = array(); | ||
| 38 | + $mimeBoundary = md5(microtime()); | ||
| 39 | + | ||
| 40 | + foreach ($fields as $key => $val) { | ||
| 41 | + array_push($data, '--' . $mimeBoundary); | ||
| 42 | + array_push($data, "Content-Disposition: form-data; name=\"$key\""); | ||
| 43 | + array_push($data, ''); | ||
| 44 | + array_push($data, $val); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + array_push($data, '--' . $mimeBoundary); | ||
| 48 | + $finalMimeType = empty($mimeType) ? 'application/octet-stream' : $mimeType; | ||
| 49 | + $finalFileName = self::escapeQuotes($fileName); | ||
| 50 | + array_push($data, "Content-Disposition: form-data; name=\"$name\"; filename=\"$finalFileName\""); | ||
| 51 | + array_push($data, "Content-Type: $finalMimeType"); | ||
| 52 | + array_push($data, ''); | ||
| 53 | + array_push($data, $fileBody); | ||
| 54 | + | ||
| 55 | + array_push($data, '--' . $mimeBoundary . '--'); | ||
| 56 | + array_push($data, ''); | ||
| 57 | + | ||
| 58 | + $body = implode("\r\n", $data); | ||
| 59 | + $contentType = 'multipart/form-data; boundary=' . $mimeBoundary; | ||
| 60 | + $headers['Content-Type'] = $contentType; | ||
| 61 | + $request = new Request('POST', $url, $headers, $body); | ||
| 62 | + return self::sendRequest($request); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + private static function userAgent() | ||
| 66 | + { | ||
| 67 | + $sdkInfo = "QiniuPHP/" . Config::SDK_VER; | ||
| 68 | + | ||
| 69 | + $systemInfo = php_uname("s"); | ||
| 70 | + $machineInfo = php_uname("m"); | ||
| 71 | + | ||
| 72 | + $envInfo = "($systemInfo/$machineInfo)"; | ||
| 73 | + | ||
| 74 | + $phpVer = phpversion(); | ||
| 75 | + | ||
| 76 | + $ua = "$sdkInfo $envInfo PHP/$phpVer"; | ||
| 77 | + return $ua; | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + public static function sendRequest($request) | ||
| 81 | + { | ||
| 82 | + $t1 = microtime(true); | ||
| 83 | + $ch = curl_init(); | ||
| 84 | + $options = array( | ||
| 85 | + CURLOPT_USERAGENT => self::userAgent(), | ||
| 86 | + CURLOPT_RETURNTRANSFER => true, | ||
| 87 | + CURLOPT_SSL_VERIFYPEER => false, | ||
| 88 | + CURLOPT_SSL_VERIFYHOST => false, | ||
| 89 | + CURLOPT_HEADER => true, | ||
| 90 | + CURLOPT_NOBODY => false, | ||
| 91 | + CURLOPT_CUSTOMREQUEST => $request->method, | ||
| 92 | + CURLOPT_URL => $request->url, | ||
| 93 | + ); | ||
| 94 | + | ||
| 95 | + // Handle open_basedir & safe mode | ||
| 96 | + if (!ini_get('safe_mode') && !ini_get('open_basedir')) { | ||
| 97 | + $options[CURLOPT_FOLLOWLOCATION] = true; | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + if (!empty($request->headers)) { | ||
| 101 | + $headers = array(); | ||
| 102 | + foreach ($request->headers as $key => $val) { | ||
| 103 | + array_push($headers, "$key: $val"); | ||
| 104 | + } | ||
| 105 | + $options[CURLOPT_HTTPHEADER] = $headers; | ||
| 106 | + } | ||
| 107 | + curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); | ||
| 108 | + | ||
| 109 | + if (!empty($request->body)) { | ||
| 110 | + $options[CURLOPT_POSTFIELDS] = $request->body; | ||
| 111 | + } | ||
| 112 | + curl_setopt_array($ch, $options); | ||
| 113 | + $result = curl_exec($ch); | ||
| 114 | + $t2 = microtime(true); | ||
| 115 | + $duration = round($t2 - $t1, 3); | ||
| 116 | + $ret = curl_errno($ch); | ||
| 117 | + if ($ret !== 0) { | ||
| 118 | + $r = new Response(-1, $duration, array(), null, curl_error($ch)); | ||
| 119 | + curl_close($ch); | ||
| 120 | + return $r; | ||
| 121 | + } | ||
| 122 | + $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); | ||
| 123 | + $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); | ||
| 124 | + $headers = self::parseHeaders(substr($result, 0, $header_size)); | ||
| 125 | + $body = substr($result, $header_size); | ||
| 126 | + curl_close($ch); | ||
| 127 | + return new Response($code, $duration, $headers, $body, null); | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + private static function parseHeaders($raw) | ||
| 131 | + { | ||
| 132 | + $headers = array(); | ||
| 133 | + $headerLines = explode("\r\n", $raw); | ||
| 134 | + foreach ($headerLines as $line) { | ||
| 135 | + $headerLine = trim($line); | ||
| 136 | + $kv = explode(':', $headerLine); | ||
| 137 | + if (count($kv) > 1) { | ||
| 138 | + $kv[0] =self::ucwordsHyphen($kv[0]); | ||
| 139 | + $headers[$kv[0]] = trim($kv[1]); | ||
| 140 | + } | ||
| 141 | + } | ||
| 142 | + return $headers; | ||
| 143 | + } | ||
| 144 | + | ||
| 145 | + private static function escapeQuotes($str) | ||
| 146 | + { | ||
| 147 | + $find = array("\\", "\""); | ||
| 148 | + $replace = array("\\\\", "\\\""); | ||
| 149 | + return str_replace($find, $replace, $str); | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + private static function ucwordsHyphen($str) | ||
| 153 | + { | ||
| 154 | + return str_replace('- ', '-', ucwords(str_replace('-', '- ', $str))); | ||
| 155 | + } | ||
| 156 | +} |
vendor/Qiniu/src/Qiniu/Http/Error.php
0 → 100755
| 1 | +<?php | ||
| 2 | +namespace Qiniu\Http; | ||
| 3 | + | ||
| 4 | +/** | ||
| 5 | + * 七牛业务请求逻辑错误封装类,主要用来解析API请求返回如下的内容: | ||
| 6 | + * <pre> | ||
| 7 | + * {"error" : "detailed error message"} | ||
| 8 | + * </pre> | ||
| 9 | + */ | ||
| 10 | +final class Error | ||
| 11 | +{ | ||
| 12 | + private $url; | ||
| 13 | + private $response; | ||
| 14 | + | ||
| 15 | + public function __construct($url, $response) | ||
| 16 | + { | ||
| 17 | + $this->url = $url; | ||
| 18 | + $this->response = $response; | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + public function code() | ||
| 22 | + { | ||
| 23 | + return $this->response->statusCode; | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + public function getResponse() | ||
| 27 | + { | ||
| 28 | + return $this->response; | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + public function message() | ||
| 32 | + { | ||
| 33 | + return $this->response->error; | ||
| 34 | + } | ||
| 35 | +} |
vendor/Qiniu/src/Qiniu/Http/Request.php
0 → 100755
| 1 | +<?php | ||
| 2 | +namespace Qiniu\Http; | ||
| 3 | + | ||
| 4 | +final class Request | ||
| 5 | +{ | ||
| 6 | + public $url; | ||
| 7 | + public $headers; | ||
| 8 | + public $body; | ||
| 9 | + public $method; | ||
| 10 | + | ||
| 11 | + public function __construct($method, $url, array $headers = array(), $body = null) | ||
| 12 | + { | ||
| 13 | + $this->method = strtoupper($method); | ||
| 14 | + $this->url = $url; | ||
| 15 | + $this->headers = $headers; | ||
| 16 | + $this->body = $body; | ||
| 17 | + } | ||
| 18 | +} |
vendor/Qiniu/src/Qiniu/Http/Response.php
0 → 100755
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace Qiniu\Http; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * HTTP response Object | ||
| 7 | + */ | ||
| 8 | +final class Response | ||
| 9 | +{ | ||
| 10 | + public $statusCode; | ||
| 11 | + public $headers; | ||
| 12 | + public $body; | ||
| 13 | + public $error; | ||
| 14 | + private $jsonData; | ||
| 15 | + public $duration; | ||
| 16 | + | ||
| 17 | + /** @var array Mapping of status codes to reason phrases */ | ||
| 18 | + private static $statusTexts = array( | ||
| 19 | + 100 => 'Continue', | ||
| 20 | + 101 => 'Switching Protocols', | ||
| 21 | + 102 => 'Processing', | ||
| 22 | + 200 => 'OK', | ||
| 23 | + 201 => 'Created', | ||
| 24 | + 202 => 'Accepted', | ||
| 25 | + 203 => 'Non-Authoritative Information', | ||
| 26 | + 204 => 'No Content', | ||
| 27 | + 205 => 'Reset Content', | ||
| 28 | + 206 => 'Partial Content', | ||
| 29 | + 207 => 'Multi-Status', | ||
| 30 | + 208 => 'Already Reported', | ||
| 31 | + 226 => 'IM Used', | ||
| 32 | + 300 => 'Multiple Choices', | ||
| 33 | + 301 => 'Moved Permanently', | ||
| 34 | + 302 => 'Found', | ||
| 35 | + 303 => 'See Other', | ||
| 36 | + 304 => 'Not Modified', | ||
| 37 | + 305 => 'Use Proxy', | ||
| 38 | + 307 => 'Temporary Redirect', | ||
| 39 | + 308 => 'Permanent Redirect', | ||
| 40 | + 400 => 'Bad Request', | ||
| 41 | + 401 => 'Unauthorized', | ||
| 42 | + 402 => 'Payment Required', | ||
| 43 | + 403 => 'Forbidden', | ||
| 44 | + 404 => 'Not Found', | ||
| 45 | + 405 => 'Method Not Allowed', | ||
| 46 | + 406 => 'Not Acceptable', | ||
| 47 | + 407 => 'Proxy Authentication Required', | ||
| 48 | + 408 => 'Request Timeout', | ||
| 49 | + 409 => 'Conflict', | ||
| 50 | + 410 => 'Gone', | ||
| 51 | + 411 => 'Length Required', | ||
| 52 | + 412 => 'Precondition Failed', | ||
| 53 | + 413 => 'Request Entity Too Large', | ||
| 54 | + 414 => 'Request-URI Too Long', | ||
| 55 | + 415 => 'Unsupported Media Type', | ||
| 56 | + 416 => 'Requested Range Not Satisfiable', | ||
| 57 | + 417 => 'Expectation Failed', | ||
| 58 | + 422 => 'Unprocessable Entity', | ||
| 59 | + 423 => 'Locked', | ||
| 60 | + 424 => 'Failed Dependency', | ||
| 61 | + 425 => 'Reserved for WebDAV advanced collections expired proposal', | ||
| 62 | + 426 => 'Upgrade required', | ||
| 63 | + 428 => 'Precondition Required', | ||
| 64 | + 429 => 'Too Many Requests', | ||
| 65 | + 431 => 'Request Header Fields Too Large', | ||
| 66 | + 500 => 'Internal Server Error', | ||
| 67 | + 501 => 'Not Implemented', | ||
| 68 | + 502 => 'Bad Gateway', | ||
| 69 | + 503 => 'Service Unavailable', | ||
| 70 | + 504 => 'Gateway Timeout', | ||
| 71 | + 505 => 'HTTP Version Not Supported', | ||
| 72 | + 506 => 'Variant Also Negotiates (Experimental)', | ||
| 73 | + 507 => 'Insufficient Storage', | ||
| 74 | + 508 => 'Loop Detected', | ||
| 75 | + 510 => 'Not Extended', | ||
| 76 | + 511 => 'Network Authentication Required', | ||
| 77 | + ); | ||
| 78 | + | ||
| 79 | + /** | ||
| 80 | + * @param int $code 状态码 | ||
| 81 | + * @param double $duration 请求时长 | ||
| 82 | + * @param array $headers 响应头部 | ||
| 83 | + * @param string $body 响应内容 | ||
| 84 | + * @param string $error 错误描述 | ||
| 85 | + */ | ||
| 86 | + public function __construct($code, $duration, array $headers = array(), $body = null, $error = null) | ||
| 87 | + { | ||
| 88 | + $this->statusCode = $code; | ||
| 89 | + $this->duration = $duration; | ||
| 90 | + $this->headers = $headers; | ||
| 91 | + $this->body = $body; | ||
| 92 | + $this->error = $error; | ||
| 93 | + $this->jsonData = null; | ||
| 94 | + if ($error !== null) { | ||
| 95 | + return; | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + if ($body === null) { | ||
| 99 | + if ($code >= 400) { | ||
| 100 | + $this->error = self::$statusTexts[$code]; | ||
| 101 | + } | ||
| 102 | + return; | ||
| 103 | + } | ||
| 104 | + if (self::isJson($headers)) { | ||
| 105 | + try { | ||
| 106 | + $jsonData = self::bodyJson($body); | ||
| 107 | + if ($code >= 400) { | ||
| 108 | + $this->error = $body; | ||
| 109 | + if ($jsonData['error'] !== null) { | ||
| 110 | + $this->error = $jsonData['error']; | ||
| 111 | + } | ||
| 112 | + } | ||
| 113 | + $this->jsonData = $jsonData; | ||
| 114 | + } catch (\InvalidArgumentException $e) { | ||
| 115 | + $this->error = $body; | ||
| 116 | + if ($code >= 200 && $code < 300) { | ||
| 117 | + $this->error = $e->getMessage(); | ||
| 118 | + } | ||
| 119 | + } | ||
| 120 | + } elseif ($code >= 400) { | ||
| 121 | + $this->error = $body; | ||
| 122 | + } | ||
| 123 | + return; | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + public function json() | ||
| 127 | + { | ||
| 128 | + return $this->jsonData; | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + private static function bodyJson($body) | ||
| 132 | + { | ||
| 133 | + return \Qiniu\json_decode((string) $body, true, 512); | ||
| 134 | + } | ||
| 135 | + | ||
| 136 | + public function xVia() | ||
| 137 | + { | ||
| 138 | + $via = $this->headers['X-Via']; | ||
| 139 | + if ($via === null) { | ||
| 140 | + $via = $this->headers['X-Px']; | ||
| 141 | + } | ||
| 142 | + if ($via === null) { | ||
| 143 | + $via = $this->headers['Fw-Via']; | ||
| 144 | + } | ||
| 145 | + return $via; | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | + public function xLog() | ||
| 149 | + { | ||
| 150 | + return $this->headers['X-Log']; | ||
| 151 | + } | ||
| 152 | + | ||
| 153 | + public function xReqId() | ||
| 154 | + { | ||
| 155 | + return $this->headers['X-Reqid']; | ||
| 156 | + } | ||
| 157 | + | ||
| 158 | + public function ok() | ||
| 159 | + { | ||
| 160 | + return $this->statusCode >= 200 && $this->statusCode < 300 && $this->error === null; | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + public function needRetry() | ||
| 164 | + { | ||
| 165 | + $code = $this->statusCode; | ||
| 166 | + if ($code < 0 || ($code / 100 === 5 and $code !== 579) || $code === 996) { | ||
| 167 | + return true; | ||
| 168 | + } | ||
| 169 | + } | ||
| 170 | + | ||
| 171 | + private static function isJson($headers) | ||
| 172 | + { | ||
| 173 | + return array_key_exists('Content-Type', $headers) && | ||
| 174 | + strpos($headers['Content-Type'], 'application/json') === 0; | ||
| 175 | + } | ||
| 176 | +} |
| 1 | +<?php | ||
| 2 | +namespace Qiniu\Processing; | ||
| 3 | + | ||
| 4 | +use Qiniu; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * 主要涉及图片链接拼接 | ||
| 8 | + * | ||
| 9 | + * @link http://developer.qiniu.com/code/v6/api/kodo-api/image/imageview2.html | ||
| 10 | + */ | ||
| 11 | +final class ImageUrlBuilder | ||
| 12 | +{ | ||
| 13 | + /** | ||
| 14 | + * mode合法范围值 | ||
| 15 | + * | ||
| 16 | + * @var array | ||
| 17 | + */ | ||
| 18 | + protected $modeArr = array(0, 1, 2, 3, 4, 5); | ||
| 19 | + | ||
| 20 | + /** | ||
| 21 | + * format合法值 | ||
| 22 | + * | ||
| 23 | + * @var array | ||
| 24 | + */ | ||
| 25 | + protected $formatArr = array('psd', 'jpeg', 'png', 'gif', 'webp', 'tiff', 'bmp'); | ||
| 26 | + | ||
| 27 | + /** | ||
| 28 | + * 水印图片位置合法值 | ||
| 29 | + * | ||
| 30 | + * @var array | ||
| 31 | + */ | ||
| 32 | + protected $gravityArr = array('NorthWest', 'North', 'NorthEast', | ||
| 33 | + 'West', 'Center', 'East', 'SouthWest', 'South', 'SouthEast'); | ||
| 34 | + | ||
| 35 | + /** | ||
| 36 | + * 缩略图链接拼接 | ||
| 37 | + * | ||
| 38 | + * @param string $url 图片链接 | ||
| 39 | + * @param int $mode 缩略模式 | ||
| 40 | + * @param int $width 宽度 | ||
| 41 | + * @param int $height 长度 | ||
| 42 | + * @param string $format 输出类型 | ||
| 43 | + * @param int $quality 图片质量 | ||
| 44 | + * @param int $interlace 是否支持渐进显示 | ||
| 45 | + * @param int $ignoreError 忽略结果 | ||
| 46 | + * @return string | ||
| 47 | + * @link http://developer.qiniu.com/code/v6/api/kodo-api/image/imageview2.html | ||
| 48 | + * @author Sherlock Ren <sherlock_ren@icloud.com> | ||
| 49 | + */ | ||
| 50 | + public function thumbnail( | ||
| 51 | + $url, | ||
| 52 | + $mode, | ||
| 53 | + $width, | ||
| 54 | + $height, | ||
| 55 | + $format = null, | ||
| 56 | + $interlace = null, | ||
| 57 | + $quality = null, | ||
| 58 | + $ignoreError = 1 | ||
| 59 | + ) { | ||
| 60 | + | ||
| 61 | + // url合法效验 | ||
| 62 | + if (!$this->isUrl($url)) { | ||
| 63 | + return $url; | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + // 参数合法性效验 | ||
| 67 | + if (!in_array(intval($mode), $this->modeArr, true)) { | ||
| 68 | + return $url; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + if (!$width || !$height) { | ||
| 72 | + return $url; | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + $thumbStr = 'imageView2/' . $mode . '/w/' . $width . '/h/' . $height . '/'; | ||
| 76 | + | ||
| 77 | + // 拼接输出格式 | ||
| 78 | + if (!is_null($format) | ||
| 79 | + && in_array($format, $this->formatArr) | ||
| 80 | + ) { | ||
| 81 | + $thumbStr .= 'format/' . $format . '/'; | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + // 拼接渐进显示 | ||
| 85 | + if (!is_null($interlace) | ||
| 86 | + && in_array(intval($interlace), array(0, 1), true) | ||
| 87 | + ) { | ||
| 88 | + $thumbStr .= 'interlace/' . $interlace . '/'; | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + // 拼接图片质量 | ||
| 92 | + if (!is_null($quality) | ||
| 93 | + && intval($quality) >= 0 | ||
| 94 | + && intval($quality) <= 100 | ||
| 95 | + ) { | ||
| 96 | + $thumbStr .= 'q/' . $quality . '/'; | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + $thumbStr .= 'ignore-error/' . $ignoreError . '/'; | ||
| 100 | + | ||
| 101 | + // 如果有query_string用|线分割实现多参数 | ||
| 102 | + return $url . ($this->hasQuery($url) ? '|' : '?') . $thumbStr; | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + /** | ||
| 106 | + * 图片水印 | ||
| 107 | + * | ||
| 108 | + * @param string $url 图片链接 | ||
| 109 | + * @param string $image 水印图片链接 | ||
| 110 | + * @param numeric $dissolve 透明度 | ||
| 111 | + * @param string $gravity 水印位置 | ||
| 112 | + * @param numeric $dx 横轴边距 | ||
| 113 | + * @param numeric $dy 纵轴边距 | ||
| 114 | + * @param numeric $watermarkScale 自适应原图的短边比例 | ||
| 115 | + * @link http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html | ||
| 116 | + * @return string | ||
| 117 | + * @author Sherlock Ren <sherlock_ren@icloud.com> | ||
| 118 | + */ | ||
| 119 | + public function waterImg( | ||
| 120 | + $url, | ||
| 121 | + $image, | ||
| 122 | + $dissolve = 100, | ||
| 123 | + $gravity = 'SouthEast', | ||
| 124 | + $dx = null, | ||
| 125 | + $dy = null, | ||
| 126 | + $watermarkScale = null | ||
| 127 | + ) { | ||
| 128 | + // url合法效验 | ||
| 129 | + if (!$this->isUrl($url)) { | ||
| 130 | + return $url; | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + $waterStr = 'watermark/1/image/' . \Qiniu\base64_urlSafeEncode($image) . '/'; | ||
| 134 | + | ||
| 135 | + // 拼接水印透明度 | ||
| 136 | + if (is_numeric($dissolve) | ||
| 137 | + && $dissolve <= 100 | ||
| 138 | + ) { | ||
| 139 | + $waterStr .= 'dissolve/' . $dissolve . '/'; | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | + // 拼接水印位置 | ||
| 143 | + if (in_array($gravity, $this->gravityArr, true)) { | ||
| 144 | + $waterStr .= 'gravity/' . $gravity . '/'; | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | + // 拼接横轴边距 | ||
| 148 | + if (!is_null($dx) | ||
| 149 | + && is_numeric($dx) | ||
| 150 | + ) { | ||
| 151 | + $waterStr .= 'dx/' . $dx . '/'; | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + // 拼接纵轴边距 | ||
| 155 | + if (!is_null($dy) | ||
| 156 | + && is_numeric($dy) | ||
| 157 | + ) { | ||
| 158 | + $waterStr .= 'dy/' . $dy . '/'; | ||
| 159 | + } | ||
| 160 | + | ||
| 161 | + // 拼接自适应原图的短边比例 | ||
| 162 | + if (!is_null($watermarkScale) | ||
| 163 | + && is_numeric($watermarkScale) | ||
| 164 | + && $watermarkScale > 0 | ||
| 165 | + && $watermarkScale < 1 | ||
| 166 | + ) { | ||
| 167 | + $waterStr .= 'ws/' . $watermarkScale . '/'; | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + // 如果有query_string用|线分割实现多参数 | ||
| 171 | + return $url . ($this->hasQuery($url) ? '|' : '?') . $waterStr; | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + /** | ||
| 175 | + * 文字水印 | ||
| 176 | + * | ||
| 177 | + * @param string $url 图片链接 | ||
| 178 | + * @param string $text 文字 | ||
| 179 | + * @param string $font 文字字体 | ||
| 180 | + * @param string $fontSize 文字字号 | ||
| 181 | + * @param string $fontColor 文字颜色 | ||
| 182 | + * @param numeric $dissolve 透明度 | ||
| 183 | + * @param string $gravity 水印位置 | ||
| 184 | + * @param numeric $dx 横轴边距 | ||
| 185 | + * @param numeric $dy 纵轴边距 | ||
| 186 | + * @link http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html#text-watermark | ||
| 187 | + * @return string | ||
| 188 | + * @author Sherlock Ren <sherlock_ren@icloud.com> | ||
| 189 | + */ | ||
| 190 | + public function waterText( | ||
| 191 | + $url, | ||
| 192 | + $text, | ||
| 193 | + $font = '黑体', | ||
| 194 | + $fontSize = 0, | ||
| 195 | + $fontColor = null, | ||
| 196 | + $dissolve = 100, | ||
| 197 | + $gravity = 'SouthEast', | ||
| 198 | + $dx = null, | ||
| 199 | + $dy = null | ||
| 200 | + ) { | ||
| 201 | + // url合法效验 | ||
| 202 | + if (!$this->isUrl($url)) { | ||
| 203 | + return $url; | ||
| 204 | + } | ||
| 205 | + | ||
| 206 | + $waterStr = 'watermark/2/text/' | ||
| 207 | + . \Qiniu\base64_urlSafeEncode($text) . '/font/' | ||
| 208 | + . \Qiniu\base64_urlSafeEncode($font) . '/'; | ||
| 209 | + | ||
| 210 | + // 拼接文字大小 | ||
| 211 | + if (is_int($fontSize)) { | ||
| 212 | + $waterStr .= 'fontsize/' . $fontSize . '/'; | ||
| 213 | + } | ||
| 214 | + | ||
| 215 | + // 拼接文字颜色 | ||
| 216 | + if (!is_null($fontColor) | ||
| 217 | + && $fontColor | ||
| 218 | + ) { | ||
| 219 | + $waterStr .= 'fill/' . \Qiniu\base64_urlSafeEncode($fontColor) . '/'; | ||
| 220 | + } | ||
| 221 | + | ||
| 222 | + // 拼接水印透明度 | ||
| 223 | + if (is_numeric($dissolve) | ||
| 224 | + && $dissolve <= 100 | ||
| 225 | + ) { | ||
| 226 | + $waterStr .= 'dissolve/' . $dissolve . '/'; | ||
| 227 | + } | ||
| 228 | + | ||
| 229 | + // 拼接水印位置 | ||
| 230 | + if (in_array($gravity, $this->gravityArr, true)) { | ||
| 231 | + $waterStr .= 'gravity/' . $gravity . '/'; | ||
| 232 | + } | ||
| 233 | + | ||
| 234 | + // 拼接横轴边距 | ||
| 235 | + if (!is_null($dx) | ||
| 236 | + && is_numeric($dx) | ||
| 237 | + ) { | ||
| 238 | + $waterStr .= 'dx/' . $dx . '/'; | ||
| 239 | + } | ||
| 240 | + | ||
| 241 | + // 拼接纵轴边距 | ||
| 242 | + if (!is_null($dy) | ||
| 243 | + && is_numeric($dy) | ||
| 244 | + ) { | ||
| 245 | + $waterStr .= 'dy/' . $dy . '/'; | ||
| 246 | + } | ||
| 247 | + | ||
| 248 | + // 如果有query_string用|线分割实现多参数 | ||
| 249 | + return $url . ($this->hasQuery($url) ? '|' : '?') . $waterStr; | ||
| 250 | + } | ||
| 251 | + | ||
| 252 | + /** | ||
| 253 | + * 效验url合法性 | ||
| 254 | + * | ||
| 255 | + * @param string $url url链接 | ||
| 256 | + * @return string | ||
| 257 | + * @author Sherlock Ren <sherlock_ren@icloud.com> | ||
| 258 | + */ | ||
| 259 | + protected function isUrl($url) | ||
| 260 | + { | ||
| 261 | + $urlArr = parse_url($url); | ||
| 262 | + | ||
| 263 | + return $urlArr['scheme'] | ||
| 264 | + && in_array($urlArr['scheme'], array('http', 'https')) | ||
| 265 | + && $urlArr['host'] | ||
| 266 | + && $urlArr['path']; | ||
| 267 | + } | ||
| 268 | + | ||
| 269 | + /** | ||
| 270 | + * 检测是否有query | ||
| 271 | + * | ||
| 272 | + * @param string $url url链接 | ||
| 273 | + * @return string | ||
| 274 | + * @author Sherlock Ren <sherlock_ren@icloud.com> | ||
| 275 | + */ | ||
| 276 | + protected function hasQuery($url) | ||
| 277 | + { | ||
| 278 | + $urlArr = parse_url($url); | ||
| 279 | + | ||
| 280 | + return !empty($urlArr['query']); | ||
| 281 | + } | ||
| 282 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace Qiniu\Processing; | ||
| 4 | + | ||
| 5 | +use Qiniu\Http\Client; | ||
| 6 | +use Qiniu\Http\Error; | ||
| 7 | + | ||
| 8 | +final class Operation | ||
| 9 | +{ | ||
| 10 | + | ||
| 11 | + private $auth; | ||
| 12 | + private $token_expire; | ||
| 13 | + private $domain; | ||
| 14 | + | ||
| 15 | + public function __construct($domain, $auth = null, $token_expire = 3600) | ||
| 16 | + { | ||
| 17 | + $this->auth = $auth; | ||
| 18 | + $this->domain = $domain; | ||
| 19 | + $this->token_expire = $token_expire; | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + /** | ||
| 24 | + * 对资源文件进行处理 | ||
| 25 | + * | ||
| 26 | + * @param $key 待处理的资源文件名 | ||
| 27 | + * @param $fops string|array fop操作,多次fop操作以array的形式传入。 | ||
| 28 | + * eg. imageView2/1/w/200/h/200, imageMogr2/thumbnail/!75px | ||
| 29 | + * | ||
| 30 | + * @return array 文件处理后的结果及错误。 | ||
| 31 | + * | ||
| 32 | + * @link http://developer.qiniu.com/docs/v6/api/reference/fop/ | ||
| 33 | + */ | ||
| 34 | + public function execute($key, $fops) | ||
| 35 | + { | ||
| 36 | + $url = $this->buildUrl($key, $fops); | ||
| 37 | + $resp = Client::get($url); | ||
| 38 | + if (!$resp->ok()) { | ||
| 39 | + return array(null, new Error($url, $resp)); | ||
| 40 | + } | ||
| 41 | + if ($resp->json() !== null) { | ||
| 42 | + return array($resp->json(), null); | ||
| 43 | + } | ||
| 44 | + return array($resp->body, null); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + public function buildUrl($key, $fops, $protocol = 'http') | ||
| 48 | + { | ||
| 49 | + if (is_array($fops)) { | ||
| 50 | + $fops = implode('|', $fops); | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + $url = $protocol . "://$this->domain/$key?$fops"; | ||
| 54 | + if ($this->auth !== null) { | ||
| 55 | + $url = $this->auth->privateDownloadUrl($url, $this->token_expire); | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + return $url; | ||
| 59 | + } | ||
| 60 | +} |
| 1 | +<?php | ||
| 2 | +namespace Qiniu\Processing; | ||
| 3 | + | ||
| 4 | +use Qiniu\Config; | ||
| 5 | +use Qiniu\Http\Client; | ||
| 6 | +use Qiniu\Http\Error; | ||
| 7 | +use Qiniu\Processing\Operation; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * 持久化处理类,该类用于主动触发异步持久化操作. | ||
| 11 | + * | ||
| 12 | + * @link http://developer.qiniu.com/docs/v6/api/reference/fop/pfop/pfop.html | ||
| 13 | + */ | ||
| 14 | +final class PersistentFop | ||
| 15 | +{ | ||
| 16 | + /** | ||
| 17 | + * @var 账号管理密钥对,Auth对象 | ||
| 18 | + */ | ||
| 19 | + private $auth; | ||
| 20 | + | ||
| 21 | + /* | ||
| 22 | + * @var 配置对象,Config 对象 | ||
| 23 | + * */ | ||
| 24 | + private $config; | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + public function __construct($auth, $config = null) | ||
| 28 | + { | ||
| 29 | + $this->auth = $auth; | ||
| 30 | + if ($config == null) { | ||
| 31 | + $this->config = new Config(); | ||
| 32 | + } else { | ||
| 33 | + $this->config = $config; | ||
| 34 | + } | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + /** | ||
| 38 | + * 对资源文件进行异步持久化处理 | ||
| 39 | + * @param $bucket 资源所在空间 | ||
| 40 | + * @param $key 待处理的源文件 | ||
| 41 | + * @param $fops string|array 待处理的pfop操作,多个pfop操作以array的形式传入。 | ||
| 42 | + * eg. avthumb/mp3/ab/192k, vframe/jpg/offset/7/w/480/h/360 | ||
| 43 | + * @param $pipeline 资源处理队列 | ||
| 44 | + * @param $notify_url 处理结果通知地址 | ||
| 45 | + * @param $force 是否强制执行一次新的指令 | ||
| 46 | + * | ||
| 47 | + * | ||
| 48 | + * @return array 返回持久化处理的persistentId, 和返回的错误。 | ||
| 49 | + * | ||
| 50 | + * @link http://developer.qiniu.com/docs/v6/api/reference/fop/ | ||
| 51 | + */ | ||
| 52 | + public function execute($bucket, $key, $fops, $pipeline = null, $notify_url = null, $force = false) | ||
| 53 | + { | ||
| 54 | + if (is_array($fops)) { | ||
| 55 | + $fops = implode(';', $fops); | ||
| 56 | + } | ||
| 57 | + $params = array('bucket' => $bucket, 'key' => $key, 'fops' => $fops); | ||
| 58 | + \Qiniu\setWithoutEmpty($params, 'pipeline', $pipeline); | ||
| 59 | + \Qiniu\setWithoutEmpty($params, 'notifyURL', $notify_url); | ||
| 60 | + if ($force) { | ||
| 61 | + $params['force'] = 1; | ||
| 62 | + } | ||
| 63 | + $data = http_build_query($params); | ||
| 64 | + $scheme = "http://"; | ||
| 65 | + if ($this->config->useHTTPS === true) { | ||
| 66 | + $scheme = "https://"; | ||
| 67 | + } | ||
| 68 | + $url = $scheme . Config::API_HOST . '/pfop/'; | ||
| 69 | + $headers = $this->auth->authorization($url, $data, 'application/x-www-form-urlencoded'); | ||
| 70 | + $headers['Content-Type'] = 'application/x-www-form-urlencoded'; | ||
| 71 | + $response = Client::post($url, $data, $headers); | ||
| 72 | + if (!$response->ok()) { | ||
| 73 | + return array(null, new Error($url, $response)); | ||
| 74 | + } | ||
| 75 | + $r = $response->json(); | ||
| 76 | + $id = $r['persistentId']; | ||
| 77 | + return array($id, null); | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + public function status($id) | ||
| 81 | + { | ||
| 82 | + $scheme = "http://"; | ||
| 83 | + | ||
| 84 | + if ($this->config->useHTTPS === true) { | ||
| 85 | + $scheme = "https://"; | ||
| 86 | + } | ||
| 87 | + $url = $scheme . Config::API_HOST . "/status/get/prefop?id=$id"; | ||
| 88 | + $response = Client::get($url); | ||
| 89 | + if (!$response->ok()) { | ||
| 90 | + return array(null, new Error($url, $response)); | ||
| 91 | + } | ||
| 92 | + return array($response->json(), null); | ||
| 93 | + } | ||
| 94 | +} |
vendor/Qiniu/src/Qiniu/Rtc/AppClient.php
0 → 100755
| 1 | +<?php | ||
| 2 | +namespace Qiniu\Rtc; | ||
| 3 | + | ||
| 4 | +use Qiniu\Http\Client; | ||
| 5 | +use Qiniu\Http\Error; | ||
| 6 | +use Qiniu\Config; | ||
| 7 | +use Qiniu\Auth; | ||
| 8 | + | ||
| 9 | +class AppClient | ||
| 10 | +{ | ||
| 11 | + private $auth; | ||
| 12 | + private $baseURL; | ||
| 13 | + | ||
| 14 | + public function __construct(Auth $auth) | ||
| 15 | + { | ||
| 16 | + $this->auth = $auth; | ||
| 17 | + | ||
| 18 | + $this->baseURL = sprintf("%s/%s/apps", Config::RTCAPI_HOST, Config::RTCAPI_VERSION); | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + /* | ||
| 22 | + * hub: 直播空间名 | ||
| 23 | + * title: app 的名称 注意,Title 不是唯一标识,重复 create 动作将生成多个 app | ||
| 24 | + * maxUsers:人数限制 | ||
| 25 | + * NoAutoKickUser: bool 类型,可选,禁止自动踢人(抢流)。默认为 false , | ||
| 26 | + 即同一个身份的 client (app/room/user) ,新的连麦请求可以成功,旧连接被关闭。 | ||
| 27 | + */ | ||
| 28 | + public function createApp($hub, $title, $maxUsers = null, $noAutoKickUser = null) | ||
| 29 | + { | ||
| 30 | + $params['hub'] = $hub; | ||
| 31 | + $params['title'] = $title; | ||
| 32 | + if (!empty($maxUsers)) { | ||
| 33 | + $params['maxUsers'] = $maxUsers; | ||
| 34 | + } | ||
| 35 | + if (!empty($noAutoKickUser)) { | ||
| 36 | + $params['noAutoKickUser'] = $noAutoKickUser; | ||
| 37 | + } | ||
| 38 | + $body = json_encode($params); | ||
| 39 | + $ret = $this->post($this->baseURL, $body); | ||
| 40 | + return $ret; | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + /* | ||
| 44 | + * appId: app 的唯一标识,创建的时候由系统生成。 | ||
| 45 | + * Title: app 的名称, 可选。 | ||
| 46 | + * Hub: 绑定的直播 hub,可选,用于合流后 rtmp 推流。 | ||
| 47 | + * MaxUsers: int 类型,可选,连麦房间支持的最大在线人数。 | ||
| 48 | + * NoAutoKickUser: bool 类型,可选,禁止自动踢人。 | ||
| 49 | + * MergePublishRtmp: 连麦合流转推 RTMP 的配置,可选择。其详细配置包括如下 | ||
| 50 | + Enable: 布尔类型,用于开启和关闭所有房间的合流功能。 | ||
| 51 | + AudioOnly: 布尔类型,可选,指定是否只合成音频。 | ||
| 52 | + Height, Width: int64,可选,指定合流输出的高和宽,默认为 640 x 480。 | ||
| 53 | + OutputFps: int64,可选,指定合流输出的帧率,默认为 25 fps 。 | ||
| 54 | + OutputKbps: int64,可选,指定合流输出的码率,默认为 1000 。 | ||
| 55 | + URL: 合流后转推旁路直播的地址,可选,支持魔法变量配置按照连麦房间号生成不同的推流地址。如果是转推到七牛直播云,不建议使用该配置。 | ||
| 56 | + StreamTitle: 转推七牛直播云的流名,可选,支持魔法变量配置按照连麦房间号生成不同的流名。例如,配置 Hub 为 qn-zhibo ,配置 StreamTitle 为 $(roomName) ,则房间 meeting-001 的合流将会被转推到 rtmp://pili-publish.qn-zhibo.***.com/qn-zhibo/meeting-001地址。详细配置细则,请咨询七牛技术支持。 | ||
| 57 | + */ | ||
| 58 | + public function updateApp($appId, $hub, $title, $maxUsers = null, $mergePublishRtmp = null, $noAutoKickUser = null) | ||
| 59 | + { | ||
| 60 | + $url = $this->baseURL . '/' . $appId; | ||
| 61 | + $params['hub'] = $hub; | ||
| 62 | + $params['title'] = $title; | ||
| 63 | + if (!empty($maxUsers)) { | ||
| 64 | + $params['maxUsers'] = $maxUsers; | ||
| 65 | + } | ||
| 66 | + if (!empty($noAutoKickUser)) { | ||
| 67 | + $params['noAutoKickUser'] = $noAutoKickUser; | ||
| 68 | + } | ||
| 69 | + if (!empty($mergePublishRtmp)) { | ||
| 70 | + $params['mergePublishRtmp'] = $mergePublishRtmp; | ||
| 71 | + } | ||
| 72 | + $body = json_encode($params); | ||
| 73 | + $ret = $this->post($url, $body); | ||
| 74 | + return $ret; | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + /* | ||
| 78 | + * appId: app 的唯一标识,创建的时候由系统生成。 | ||
| 79 | + */ | ||
| 80 | + public function getApp($appId) | ||
| 81 | + { | ||
| 82 | + $url = $this->baseURL . '/' . $appId; | ||
| 83 | + $ret = $this->get($url); | ||
| 84 | + return $ret; | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + /* | ||
| 88 | + * appId: app 的唯一标识,创建的时候由系统生成 | ||
| 89 | + */ | ||
| 90 | + public function deleteApp($appId) | ||
| 91 | + { | ||
| 92 | + $url = $this->baseURL . '/' . $appId; | ||
| 93 | + list(, $err) = $this->delete($url); | ||
| 94 | + return $err; | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + /* | ||
| 98 | + * 获取房间的人数 | ||
| 99 | + * appId: app 的唯一标识,创建的时候由系统生成。 | ||
| 100 | + * roomName: 操作所查询的连麦房间。 | ||
| 101 | + */ | ||
| 102 | + public function listUser($appId, $roomName) | ||
| 103 | + { | ||
| 104 | + $url = sprintf("%s/%s/rooms/%s/users", $this->baseURL, $appId, $roomName); | ||
| 105 | + $ret = $this->get($url); | ||
| 106 | + return $ret; | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + /* | ||
| 110 | + * 踢出玩家 | ||
| 111 | + * appId: app 的唯一标识,创建的时候由系统生成。 | ||
| 112 | + * roomName: 连麦房间 | ||
| 113 | + * userId: 请求加入房间的用户ID | ||
| 114 | + */ | ||
| 115 | + public function kickUser($appId, $roomName, $userId) | ||
| 116 | + { | ||
| 117 | + $url = sprintf("%s/%s/rooms/%s/users/%s", $this->baseURL, $appId, $roomName, $userId); | ||
| 118 | + list(, $err) = $this->delete($url); | ||
| 119 | + return $err; | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + /* | ||
| 123 | + * 获取房间的人数 | ||
| 124 | + * appId: app 的唯一标识,创建的时候由系统生成。 | ||
| 125 | + * prefix: 所查询房间名的前缀索引,可以为空。 | ||
| 126 | + * offset: int 类型,分页查询的位移标记。 | ||
| 127 | + * limit: int 类型,此次查询的最大长度。 | ||
| 128 | + * GET /v3/apps/<AppID>/rooms?prefix=<RoomNamePrefix>&offset=<Offset>&limit=<Limit> | ||
| 129 | + */ | ||
| 130 | + public function listActiveRooms($appId, $prefix = null, $offset = null, $limit = null) | ||
| 131 | + { | ||
| 132 | + if (isset($prefix)) { | ||
| 133 | + $query['prefix'] = $prefix; | ||
| 134 | + } | ||
| 135 | + if (isset($offset)) { | ||
| 136 | + $query['offset'] = $offset; | ||
| 137 | + } | ||
| 138 | + if (isset($limit)) { | ||
| 139 | + $query['limit'] = $limit; | ||
| 140 | + } | ||
| 141 | + if (isset($query) && !empty($query)) { | ||
| 142 | + $query = '?' . http_build_query($query); | ||
| 143 | + $url = sprintf("%s/%s/rooms%s", $this->baseURL, $appId, $query); | ||
| 144 | + } else { | ||
| 145 | + $url = sprintf("%s/%s/rooms", $this->baseURL, $appId); | ||
| 146 | + } | ||
| 147 | + $ret = $this->get($url); | ||
| 148 | + return $ret; | ||
| 149 | + } | ||
| 150 | + | ||
| 151 | + /* | ||
| 152 | + * appId: app 的唯一标识,创建的时候由系统生成。 | ||
| 153 | + * roomName: 房间名称,需满足规格 ^[a-zA-Z0-9_-]{3,64}$ | ||
| 154 | + * userId: 请求加入房间的用户 ID,需满足规格 ^[a-zA-Z0-9_-]{3,50}$ | ||
| 155 | + * expireAt: int64 类型,鉴权的有效时间,传入以秒为单位的64位Unix | ||
| 156 | + 绝对时间,token 将在该时间后失效。 | ||
| 157 | + * permission: 该用户的房间管理权限,"admin" 或 "user",默认为 "user" 。 | ||
| 158 | + 当权限角色为 "admin" 时,拥有将其他用户移除出房间等特权. | ||
| 159 | + */ | ||
| 160 | + public function appToken($appId, $roomName, $userId, $expireAt, $permission) | ||
| 161 | + { | ||
| 162 | + $params['appId'] = $appId; | ||
| 163 | + $params['userId'] = $userId; | ||
| 164 | + $params['roomName'] = $roomName; | ||
| 165 | + $params['permission'] = $permission; | ||
| 166 | + $params['expireAt'] = $expireAt; | ||
| 167 | + $appAccessString = json_encode($params); | ||
| 168 | + return $this->auth->signWithData($appAccessString); | ||
| 169 | + } | ||
| 170 | + | ||
| 171 | + private function get($url, $cType = null) | ||
| 172 | + { | ||
| 173 | + $rtcToken = $this->auth->authorizationV2($url, "GET", null, $cType); | ||
| 174 | + $rtcToken['Content-Type'] = $cType; | ||
| 175 | + $ret = Client::get($url, $rtcToken); | ||
| 176 | + if (!$ret->ok()) { | ||
| 177 | + return array(null, new Error($url, $ret)); | ||
| 178 | + } | ||
| 179 | + return array($ret->json(), null); | ||
| 180 | + } | ||
| 181 | + | ||
| 182 | + private function delete($url, $contentType = 'application/json') | ||
| 183 | + { | ||
| 184 | + $rtcToken = $this->auth->authorizationV2($url, "DELETE", null, $contentType); | ||
| 185 | + $rtcToken['Content-Type'] = $contentType; | ||
| 186 | + $ret = Client::delete($url, $rtcToken); | ||
| 187 | + if (!$ret->ok()) { | ||
| 188 | + return array(null, new Error($url, $ret)); | ||
| 189 | + } | ||
| 190 | + return array($ret->json(), null); | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + private function post($url, $body, $contentType = 'application/json') | ||
| 194 | + { | ||
| 195 | + $rtcToken = $this->auth->authorizationV2($url, "POST", $body, $contentType); | ||
| 196 | + $rtcToken['Content-Type'] = $contentType; | ||
| 197 | + $ret = Client::post($url, $body, $rtcToken); | ||
| 198 | + if (!$ret->ok()) { | ||
| 199 | + return array(null, new Error($url, $ret)); | ||
| 200 | + } | ||
| 201 | + $r = ($ret->body === null) ? array() : $ret->json(); | ||
| 202 | + return array($r, null); | ||
| 203 | + } | ||
| 204 | +} |
vendor/Qiniu/src/Qiniu/Zone.php
0 → 100755
| 1 | +<?php | ||
| 2 | +namespace Qiniu; | ||
| 3 | + | ||
| 4 | +use Qiniu\Http\Client; | ||
| 5 | +use Qiniu\Http\Error; | ||
| 6 | + | ||
| 7 | +final class Zone | ||
| 8 | +{ | ||
| 9 | + | ||
| 10 | + //源站上传域名 | ||
| 11 | + public $srcUpHosts; | ||
| 12 | + //CDN加速上传域名 | ||
| 13 | + public $cdnUpHosts; | ||
| 14 | + //资源管理域名 | ||
| 15 | + public $rsHost; | ||
| 16 | + //资源列举域名 | ||
| 17 | + public $rsfHost; | ||
| 18 | + //资源处理域名 | ||
| 19 | + public $apiHost; | ||
| 20 | + //IOVIP域名 | ||
| 21 | + public $iovipHost; | ||
| 22 | + | ||
| 23 | + //构造一个Zone对象 | ||
| 24 | + public function __construct( | ||
| 25 | + $srcUpHosts = array(), | ||
| 26 | + $cdnUpHosts = array(), | ||
| 27 | + $rsHost = "rs.qiniu.com", | ||
| 28 | + $rsfHost = "rsf.qiniu.com", | ||
| 29 | + $apiHost = "api.qiniu.com", | ||
| 30 | + $iovipHost = null | ||
| 31 | + ) { | ||
| 32 | + | ||
| 33 | + $this->srcUpHosts = $srcUpHosts; | ||
| 34 | + $this->cdnUpHosts = $cdnUpHosts; | ||
| 35 | + $this->rsHost = $rsHost; | ||
| 36 | + $this->rsfHost = $rsfHost; | ||
| 37 | + $this->apiHost = $apiHost; | ||
| 38 | + $this->iovipHost = $iovipHost; | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + //华东机房 | ||
| 42 | + public static function zone0() | ||
| 43 | + { | ||
| 44 | + $Zone_z0 = new Zone( | ||
| 45 | + array("up.qiniup.com", 'up-jjh.qiniup.com', 'up-xs.qiniup.com'), | ||
| 46 | + array('upload.qiniup.com', 'upload-jjh.qiniup.com', 'upload-xs.qiniup.com'), | ||
| 47 | + 'rs.qbox.me', | ||
| 48 | + 'rsf.qbox.me', | ||
| 49 | + 'api.qiniu.com', | ||
| 50 | + 'iovip.qbox.me' | ||
| 51 | + ); | ||
| 52 | + return $Zone_z0; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + //华北机房 | ||
| 56 | + public static function zone1() | ||
| 57 | + { | ||
| 58 | + $Zone_z1 = new Zone( | ||
| 59 | + array('up-z1.qiniup.com'), | ||
| 60 | + array('upload-z1.qiniup.com'), | ||
| 61 | + "rs-z1.qbox.me", | ||
| 62 | + "rsf-z1.qbox.me", | ||
| 63 | + "api-z1.qiniu.com", | ||
| 64 | + "iovip-z1.qbox.me" | ||
| 65 | + ); | ||
| 66 | + | ||
| 67 | + return $Zone_z1; | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + //华南机房 | ||
| 71 | + public static function zone2() | ||
| 72 | + { | ||
| 73 | + $Zone_z2 = new Zone( | ||
| 74 | + array('up-z2.qiniup.com', 'up-dg.qiniup.com', 'up-fs.qiniup.com'), | ||
| 75 | + array('upload-z2.qiniup.com', 'upload-dg.qiniup.com', 'upload-fs.qiniup.com'), | ||
| 76 | + "rs-z2.qbox.me", | ||
| 77 | + "rsf-z2.qbox.me", | ||
| 78 | + "api-z2.qiniu.com", | ||
| 79 | + "iovip-z2.qbox.me" | ||
| 80 | + ); | ||
| 81 | + return $Zone_z2; | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + //北美机房 | ||
| 85 | + public static function zoneNa0() | ||
| 86 | + { | ||
| 87 | + //北美机房 | ||
| 88 | + $Zone_na0 = new Zone( | ||
| 89 | + array('up-na0.qiniup.com'), | ||
| 90 | + array('upload-na0.qiniup.com'), | ||
| 91 | + "rs-na0.qbox.me", | ||
| 92 | + "rsf-na0.qbox.me", | ||
| 93 | + "api-na0.qiniu.com", | ||
| 94 | + "iovip-na0.qbox.me" | ||
| 95 | + ); | ||
| 96 | + return $Zone_na0; | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + //新加坡机房 | ||
| 100 | + public static function zoneAs0() | ||
| 101 | + { | ||
| 102 | + //新加坡机房 | ||
| 103 | + $Zone_as0 = new Zone( | ||
| 104 | + array('up-as0.qiniup.com'), | ||
| 105 | + array('upload-as0.qiniup.com'), | ||
| 106 | + "rs-as0.qbox.me", | ||
| 107 | + "rsf-as0.qbox.me", | ||
| 108 | + "api-as0.qiniu.com", | ||
| 109 | + "iovip-as0.qbox.me" | ||
| 110 | + ); | ||
| 111 | + return $Zone_as0; | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + /* | ||
| 115 | + * GET /v2/query?ak=<ak>&&bucket=<bucket> | ||
| 116 | + **/ | ||
| 117 | + public static function queryZone($ak, $bucket) | ||
| 118 | + { | ||
| 119 | + $zone = new Zone(); | ||
| 120 | + $url = Config::UC_HOST . '/v2/query' . "?ak=$ak&bucket=$bucket"; | ||
| 121 | + $ret = Client::Get($url); | ||
| 122 | + if (!$ret->ok()) { | ||
| 123 | + return array(null, new Error($url, $ret)); | ||
| 124 | + } | ||
| 125 | + $r = ($ret->body === null) ? array() : $ret->json(); | ||
| 126 | + //print_r($ret); | ||
| 127 | + //parse zone; | ||
| 128 | + | ||
| 129 | + $iovipHost = $r['io']['src']['main'][0]; | ||
| 130 | + $zone->iovipHost = $iovipHost; | ||
| 131 | + $accMain = $r['up']['acc']['main'][0]; | ||
| 132 | + array_push($zone->cdnUpHosts, $accMain); | ||
| 133 | + if (isset($r['up']['acc']['backup'])) { | ||
| 134 | + foreach ($r['up']['acc']['backup'] as $key => $value) { | ||
| 135 | + array_push($zone->cdnUpHosts, $value); | ||
| 136 | + } | ||
| 137 | + } | ||
| 138 | + $srcMain = $r['up']['src']['main'][0]; | ||
| 139 | + array_push($zone->srcUpHosts, $srcMain); | ||
| 140 | + if (isset($r['up']['src']['backup'])) { | ||
| 141 | + foreach ($r['up']['src']['backup'] as $key => $value) { | ||
| 142 | + array_push($zone->srcUpHosts, $value); | ||
| 143 | + } | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + //set specific hosts | ||
| 147 | + if (strstr($zone->iovipHost, "z1") !== false) { | ||
| 148 | + $zone->rsHost = "rs-z1.qbox.me"; | ||
| 149 | + $zone->rsfHost = "rsf-z1.qbox.me"; | ||
| 150 | + $zone->apiHost = "api-z1.qiniu.com"; | ||
| 151 | + } elseif (strstr($zone->iovipHost, "z2") !== false) { | ||
| 152 | + $zone->rsHost = "rs-z2.qbox.me"; | ||
| 153 | + $zone->rsfHost = "rsf-z2.qbox.me"; | ||
| 154 | + $zone->apiHost = "api-z2.qiniu.com"; | ||
| 155 | + } elseif (strstr($zone->iovipHost, "na0") !== false) { | ||
| 156 | + $zone->rsHost = "rs-na0.qbox.me"; | ||
| 157 | + $zone->rsfHost = "rsf-na0.qbox.me"; | ||
| 158 | + $zone->apiHost = "api-na0.qiniu.com"; | ||
| 159 | + } elseif (strstr($zone->iovipHost, "as0") !== false) { | ||
| 160 | + $zone->rsHost = "rs-as0.qbox.me"; | ||
| 161 | + $zone->rsfHost = "rsf-as0.qbox.me"; | ||
| 162 | + $zone->apiHost = "api-as0.qiniu.com"; | ||
| 163 | + } else { | ||
| 164 | + $zone->rsHost = "rs.qbox.me"; | ||
| 165 | + $zone->rsfHost = "rsf.qbox.me"; | ||
| 166 | + $zone->apiHost = "api.qiniu.com"; | ||
| 167 | + } | ||
| 168 | + | ||
| 169 | + return $zone; | ||
| 170 | + } | ||
| 171 | +} |
vendor/Qiniu/src/Qiniu/functions.php
0 → 100755
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace Qiniu; | ||
| 4 | + | ||
| 5 | +use Qiniu\Config; | ||
| 6 | + | ||
| 7 | +if (!defined('QINIU_FUNCTIONS_VERSION')) { | ||
| 8 | + define('QINIU_FUNCTIONS_VERSION', Config::SDK_VER); | ||
| 9 | + | ||
| 10 | + /** | ||
| 11 | + * 计算文件的crc32检验码: | ||
| 12 | + * | ||
| 13 | + * @param $file string 待计算校验码的文件路径 | ||
| 14 | + * | ||
| 15 | + * @return string 文件内容的crc32校验码 | ||
| 16 | + */ | ||
| 17 | + function crc32_file($file) | ||
| 18 | + { | ||
| 19 | + $hash = hash_file('crc32b', $file); | ||
| 20 | + $array = unpack('N', pack('H*', $hash)); | ||
| 21 | + return sprintf('%u', $array[1]); | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + /** | ||
| 25 | + * 计算输入流的crc32检验码 | ||
| 26 | + * | ||
| 27 | + * @param $data 待计算校验码的字符串 | ||
| 28 | + * | ||
| 29 | + * @return string 输入字符串的crc32校验码 | ||
| 30 | + */ | ||
| 31 | + function crc32_data($data) | ||
| 32 | + { | ||
| 33 | + $hash = hash('crc32b', $data); | ||
| 34 | + $array = unpack('N', pack('H*', $hash)); | ||
| 35 | + return sprintf('%u', $array[1]); | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * 对提供的数据进行urlsafe的base64编码。 | ||
| 40 | + * | ||
| 41 | + * @param string $data 待编码的数据,一般为字符串 | ||
| 42 | + * | ||
| 43 | + * @return string 编码后的字符串 | ||
| 44 | + * @link http://developer.qiniu.com/docs/v6/api/overview/appendix.html#urlsafe-base64 | ||
| 45 | + */ | ||
| 46 | + function base64_urlSafeEncode($data) | ||
| 47 | + { | ||
| 48 | + $find = array('+', '/'); | ||
| 49 | + $replace = array('-', '_'); | ||
| 50 | + return str_replace($find, $replace, base64_encode($data)); | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + /** | ||
| 54 | + * 对提供的urlsafe的base64编码的数据进行解码 | ||
| 55 | + * | ||
| 56 | + * @param string $str 待解码的数据,一般为字符串 | ||
| 57 | + * | ||
| 58 | + * @return string 解码后的字符串 | ||
| 59 | + */ | ||
| 60 | + function base64_urlSafeDecode($str) | ||
| 61 | + { | ||
| 62 | + $find = array('-', '_'); | ||
| 63 | + $replace = array('+', '/'); | ||
| 64 | + return base64_decode(str_replace($find, $replace, $str)); | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + /** | ||
| 68 | + * Wrapper for JSON decode that implements error detection with helpful | ||
| 69 | + * error messages. | ||
| 70 | + * | ||
| 71 | + * @param string $json JSON data to parse | ||
| 72 | + * @param bool $assoc When true, returned objects will be converted | ||
| 73 | + * into associative arrays. | ||
| 74 | + * @param int $depth User specified recursion depth. | ||
| 75 | + * | ||
| 76 | + * @return mixed | ||
| 77 | + * @throws \InvalidArgumentException if the JSON cannot be parsed. | ||
| 78 | + * @link http://www.php.net/manual/en/function.json-decode.php | ||
| 79 | + */ | ||
| 80 | + function json_decode($json, $assoc = false, $depth = 512) | ||
| 81 | + { | ||
| 82 | + static $jsonErrors = array( | ||
| 83 | + JSON_ERROR_DEPTH => 'JSON_ERROR_DEPTH - Maximum stack depth exceeded', | ||
| 84 | + JSON_ERROR_STATE_MISMATCH => 'JSON_ERROR_STATE_MISMATCH - Underflow or the modes mismatch', | ||
| 85 | + JSON_ERROR_CTRL_CHAR => 'JSON_ERROR_CTRL_CHAR - Unexpected control character found', | ||
| 86 | + JSON_ERROR_SYNTAX => 'JSON_ERROR_SYNTAX - Syntax error, malformed JSON', | ||
| 87 | + JSON_ERROR_UTF8 => 'JSON_ERROR_UTF8 - Malformed UTF-8 characters, possibly incorrectly encoded' | ||
| 88 | + ); | ||
| 89 | + | ||
| 90 | + if (empty($json)) { | ||
| 91 | + return null; | ||
| 92 | + } | ||
| 93 | + $data = \json_decode($json, $assoc, $depth); | ||
| 94 | + | ||
| 95 | + if (JSON_ERROR_NONE !== json_last_error()) { | ||
| 96 | + $last = json_last_error(); | ||
| 97 | + throw new \InvalidArgumentException( | ||
| 98 | + 'Unable to parse JSON data: ' | ||
| 99 | + . (isset($jsonErrors[$last]) | ||
| 100 | + ? $jsonErrors[$last] | ||
| 101 | + : 'Unknown error') | ||
| 102 | + ); | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + return $data; | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + /** | ||
| 109 | + * 计算七牛API中的数据格式 | ||
| 110 | + * | ||
| 111 | + * @param $bucket 待操作的空间名 | ||
| 112 | + * @param $key 待操作的文件名 | ||
| 113 | + * | ||
| 114 | + * @return string 符合七牛API规格的数据格式 | ||
| 115 | + * @link http://developer.qiniu.com/docs/v6/api/reference/data-formats.html | ||
| 116 | + */ | ||
| 117 | + function entry($bucket, $key) | ||
| 118 | + { | ||
| 119 | + $en = $bucket; | ||
| 120 | + if (!empty($key)) { | ||
| 121 | + $en = $bucket . ':' . $key; | ||
| 122 | + } | ||
| 123 | + return base64_urlSafeEncode($en); | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + /** | ||
| 127 | + * array 辅助方法,无值时不set | ||
| 128 | + * | ||
| 129 | + * @param $array 待操作array | ||
| 130 | + * @param $key key | ||
| 131 | + * @param $value value 为null时 不设置 | ||
| 132 | + * | ||
| 133 | + * @return array 原来的array,便于连续操作 | ||
| 134 | + */ | ||
| 135 | + function setWithoutEmpty(&$array, $key, $value) | ||
| 136 | + { | ||
| 137 | + if (!empty($value)) { | ||
| 138 | + $array[$key] = $value; | ||
| 139 | + } | ||
| 140 | + return $array; | ||
| 141 | + } | ||
| 142 | + | ||
| 143 | + /** | ||
| 144 | + * 缩略图链接拼接 | ||
| 145 | + * | ||
| 146 | + * @param string $url 图片链接 | ||
| 147 | + * @param int $mode 缩略模式 | ||
| 148 | + * @param int $width 宽度 | ||
| 149 | + * @param int $height 长度 | ||
| 150 | + * @param string $format 输出类型 | ||
| 151 | + * @param int $quality 图片质量 | ||
| 152 | + * @param int $interlace 是否支持渐进显示 | ||
| 153 | + * @param int $ignoreError 忽略结果 | ||
| 154 | + * @return string | ||
| 155 | + * @link http://developer.qiniu.com/code/v6/api/kodo-api/image/imageview2.html | ||
| 156 | + * @author Sherlock Ren <sherlock_ren@icloud.com> | ||
| 157 | + */ | ||
| 158 | + function thumbnail( | ||
| 159 | + $url, | ||
| 160 | + $mode, | ||
| 161 | + $width, | ||
| 162 | + $height, | ||
| 163 | + $format = null, | ||
| 164 | + $quality = null, | ||
| 165 | + $interlace = null, | ||
| 166 | + $ignoreError = 1 | ||
| 167 | + ) { | ||
| 168 | + | ||
| 169 | + static $imageUrlBuilder = null; | ||
| 170 | + if (is_null($imageUrlBuilder)) { | ||
| 171 | + $imageUrlBuilder = new \Qiniu\Processing\ImageUrlBuilder; | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + return call_user_func_array(array($imageUrlBuilder, 'thumbnail'), func_get_args()); | ||
| 175 | + } | ||
| 176 | + | ||
| 177 | + /** | ||
| 178 | + * 图片水印 | ||
| 179 | + * | ||
| 180 | + * @param string $url 图片链接 | ||
| 181 | + * @param string $image 水印图片链接 | ||
| 182 | + * @param numeric $dissolve 透明度 | ||
| 183 | + * @param string $gravity 水印位置 | ||
| 184 | + * @param numeric $dx 横轴边距 | ||
| 185 | + * @param numeric $dy 纵轴边距 | ||
| 186 | + * @param numeric $watermarkScale 自适应原图的短边比例 | ||
| 187 | + * @link http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html | ||
| 188 | + * @return string | ||
| 189 | + * @author Sherlock Ren <sherlock_ren@icloud.com> | ||
| 190 | + */ | ||
| 191 | + function waterImg( | ||
| 192 | + $url, | ||
| 193 | + $image, | ||
| 194 | + $dissolve = 100, | ||
| 195 | + $gravity = 'SouthEast', | ||
| 196 | + $dx = null, | ||
| 197 | + $dy = null, | ||
| 198 | + $watermarkScale = null | ||
| 199 | + ) { | ||
| 200 | + | ||
| 201 | + static $imageUrlBuilder = null; | ||
| 202 | + if (is_null($imageUrlBuilder)) { | ||
| 203 | + $imageUrlBuilder = new \Qiniu\Processing\ImageUrlBuilder; | ||
| 204 | + } | ||
| 205 | + | ||
| 206 | + return call_user_func_array(array($imageUrlBuilder, 'waterImg'), func_get_args()); | ||
| 207 | + } | ||
| 208 | + | ||
| 209 | + /** | ||
| 210 | + * 文字水印 | ||
| 211 | + * | ||
| 212 | + * @param string $url 图片链接 | ||
| 213 | + * @param string $text 文字 | ||
| 214 | + * @param string $font 文字字体 | ||
| 215 | + * @param string $fontSize 文字字号 | ||
| 216 | + * @param string $fontColor 文字颜色 | ||
| 217 | + * @param numeric $dissolve 透明度 | ||
| 218 | + * @param string $gravity 水印位置 | ||
| 219 | + * @param numeric $dx 横轴边距 | ||
| 220 | + * @param numeric $dy 纵轴边距 | ||
| 221 | + * @link http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html#text-watermark | ||
| 222 | + * @return string | ||
| 223 | + * @author Sherlock Ren <sherlock_ren@icloud.com> | ||
| 224 | + */ | ||
| 225 | + function waterText( | ||
| 226 | + $url, | ||
| 227 | + $text, | ||
| 228 | + $font = '黑体', | ||
| 229 | + $fontSize = 0, | ||
| 230 | + $fontColor = null, | ||
| 231 | + $dissolve = 100, | ||
| 232 | + $gravity = 'SouthEast', | ||
| 233 | + $dx = null, | ||
| 234 | + $dy = null | ||
| 235 | + ) { | ||
| 236 | + | ||
| 237 | + static $imageUrlBuilder = null; | ||
| 238 | + if (is_null($imageUrlBuilder)) { | ||
| 239 | + $imageUrlBuilder = new \Qiniu\Processing\ImageUrlBuilder; | ||
| 240 | + } | ||
| 241 | + | ||
| 242 | + return call_user_func_array(array($imageUrlBuilder, 'waterText'), func_get_args()); | ||
| 243 | + } | ||
| 244 | + | ||
| 245 | + /** | ||
| 246 | + * 从uptoken解析accessKey和bucket | ||
| 247 | + * | ||
| 248 | + * @param $upToken | ||
| 249 | + * @return array(ak,bucket,err=null) | ||
| 250 | + */ | ||
| 251 | + function explodeUpToken($upToken) | ||
| 252 | + { | ||
| 253 | + $items = explode(':', $upToken); | ||
| 254 | + if (count($items) != 3) { | ||
| 255 | + return array(null, null, "invalid uptoken"); | ||
| 256 | + } | ||
| 257 | + $accessKey = $items[0]; | ||
| 258 | + $putPolicy = json_decode(base64_decode($items[2])); | ||
| 259 | + $scope = $putPolicy->scope; | ||
| 260 | + $scopeItems = explode(':', $scope); | ||
| 261 | + $bucket = $scopeItems[0]; | ||
| 262 | + return array($accessKey, $bucket, null); | ||
| 263 | + } | ||
| 264 | +} |
-
Please register or login to post a comment