OssServiceV2.php 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. <?php
  2. namespace app\oss\service;
  3. use app\common\service\Oss\Bucket;
  4. use app\common\service\Oss\Object;
  5. use Exception;
  6. use OSS\OssClient;
  7. use think\Config;
  8. class OssServiceV2 {
  9. static private $bucket;
  10. static private $object;
  11. public function __construct($bucketName = '') {
  12. self::$bucket = new Bucket($bucketName);
  13. self::$object = new Object($bucketName);
  14. }
  15. /**
  16. * 文件上传到阿里云
  17. * @param $filePath 保存在阿里云的路径和名称
  18. * @param $content 文件流
  19. * @param bool $isEncode 是否需要加密
  20. * @return bool|string
  21. */
  22. public function fileUpload($filePath, $content, $isEncode = true){
  23. try {
  24. $ossRes = self::$object->putObject($filePath, $content);
  25. if ($ossRes) {
  26. return $isEncode === true ? rawurlencode($filePath) : $filePath;
  27. }
  28. return false;
  29. } catch (Exception $ex) {
  30. throw new \RuntimeException('OSS ERROR MSG:' . $ex->getMessage());
  31. }
  32. }
  33. /**
  34. * 删除阿里云上的文件
  35. * @param $filePath 保存在阿里云的路径和名称
  36. * @return bool
  37. */
  38. public function fileDelete($filePath) {
  39. return self::$object->deleteObject($filePath);
  40. }
  41. /**
  42. * acl
  43. * @param $object 相对地址
  44. * @param $acl ['default', 'private', 'public-read', 'public-read-write']
  45. * @return bool
  46. */
  47. public function putObjectAcl($object, $acl='private') {
  48. return self::$object->putObjectAcl($object, $acl);
  49. }
  50. /**
  51. * 下载接口
  52. * @param $filePath
  53. * @return null
  54. */
  55. public function downFile($filePath) {
  56. return self::$object->getObject($filePath);
  57. }
  58. /**
  59. * 图片在阿里云上存在
  60. * @param $imagePath
  61. * @return bool
  62. */
  63. public function fileExist($imagePath) {
  64. return self::$object->doesObjectExist($imagePath);
  65. }
  66. /**
  67. * 图片信息
  68. * @param $imagePath
  69. * @param $ossDomain
  70. * @return mixed
  71. */
  72. public function imageInfo($imagePath, $ossDomain) {
  73. $imageInfo = file_get_contents($ossDomain . $imagePath . '@info');
  74. return json_decode($imageInfo, true);
  75. }
  76. public function bucketList() {
  77. return self::$bucket->listBuckets();
  78. }
  79. /**
  80. * 获取代签名的URI
  81. * @param array $params = [
  82. * 'object' => 'xxx',
  83. * 'bucket' => 'xxx',
  84. * 'isIntranet' => true,
  85. * 'crop' => [
  86. * 'x' => 1,
  87. * 'y' => 2,
  88. * 'w' => 3
  89. * ],
  90. * 'snapshot' => [
  91. * 't' => 1,
  92. * 'f' => 2,
  93. * 'w' => 3
  94. * ]
  95. * ]
  96. * @return string
  97. */
  98. public function getSignUrl(array $params) {
  99. $fileExist = $this->fileExist($params['object']);
  100. if (!$fileExist) {
  101. throw new \RuntimeException('未找到该文件: ' . $params['object']);
  102. }
  103. $isIntranet = isset($params['isIntranet']) ?$params['isIntranet']:true;
  104. if ((bool)$isIntranet !== true) {
  105. Config::set('ALIYUN_OSS_ENDPOINT_DOMAIN', Config::get('ALIYUN_OSS_ENDPOINT'));
  106. }
  107. $object = new Object($params['bucket']);
  108. $ossClientObj = $object->getOssClient();
  109. $ossClientObj->setUseSSL(true);
  110. $timeout = 3600;
  111. $option = '';
  112. // 图片处理
  113. if (!empty($params['resize'])) {
  114. $option = 'image/resize,m_lfit,h_' . $params['resize']['h'] . ',w_' . $params['resize']['w']; //图片缩放
  115. } else if (!empty($params['crop'])) {// 图片切割
  116. $option = 'image/crop';
  117. $keys = ['x', 'y', 'w', 'h', 'g'];
  118. foreach ($keys as $key) {
  119. if(!empty($params['crop'][$key])){
  120. $option .= ',' . $key . '_' . $params['crop'][$key];
  121. }
  122. }
  123. } else if (!empty($params['snapshot'])) {// 视频截帧
  124. $option = 'video/snapshot';
  125. //t-时间 f-格式 m-模式
  126. $keys = ['t', 'f', 'w', 'h', 'm'];
  127. foreach ($keys as $key) {
  128. if(!empty($params['snapshot'][$key])){
  129. $option .= ',' . $key . '_' . $params['snapshot'][$key];
  130. }
  131. }
  132. }
  133. $url = $ossClientObj->signUrl($params['bucket'], $params['object'], $timeout, 'GET', !empty($option) ? [OssClient::OSS_PROCESS => $option] : null);
  134. if(empty($params['url'])){
  135. return $url;
  136. }
  137. return preg_replace('#^https?:\/\/[^\/]+#', rtrim($params['url'], '\/'), $url);
  138. }
  139. /**
  140. * 批量获取签名
  141. * @param array $data = [['bucket' => xxx, 'object' => xxx],['bucket' => xxx, 'object => xxx]]
  142. * @return array
  143. */
  144. public function getMultiSignUrl(array $data){
  145. foreach ($data as $key => $dataItem) {
  146. $data[$key]['newUrl'] = $this->getSignUrl($dataItem);
  147. }
  148. return $data;
  149. }
  150. /**
  151. * 获取图片信息
  152. * @param array
  153. * @return array 图片信息
  154. */
  155. public function getPublicImageInfo($imageUrl){
  156. $imageInfoUrl = $imageUrl . '?x-oss-process=image/info';
  157. //获取oss返回的json对象
  158. return json_decode(file_get_contents($imageInfoUrl), true);
  159. }
  160. /**
  161. * 拼接成正方形
  162. * @param array $param
  163. * @return string
  164. */
  165. public function getProcessImageUrl(array $param) {
  166. // 获取图片信息
  167. $imageUrl = 'http://' . $param['bucket'] . '.' . $param['endpoint'] . $param['path'];
  168. // 取图片最短的边作为正方形的边长
  169. if (!empty($param['process']['crop']['shape']) && 'square' === $param['process']['crop']['shape']) {
  170. $imageInfo = $this->getPublicImageInfo($imageUrl);
  171. $height = $imageInfo['ImageHeight']['value'];
  172. $width = $imageInfo['ImageWidth']['value'];
  173. $param['process']['crop']['h'] = $height > $width ? $width : $height; //高
  174. $param['process']['crop']['w'] = $height > $width ? $width : $height; //宽
  175. }
  176. $processFunc = current(array_keys($param['process'])); // 获取方法(crop裁剪 resize缩放)
  177. switch ($processFunc) {
  178. case 'crop':
  179. $imageUrl .= '?x-oss-process=image/' . $processFunc;
  180. $keys = ['x', 'y', 'w', 'h', 'g'];
  181. foreach ($keys as $key) {
  182. if(!empty($param['process'][$processFunc][$key])){
  183. $imageUrl .= ',' . $key . '_' . $param['process'][$processFunc][$key];
  184. }
  185. }
  186. break;
  187. case 'resize':
  188. // 暂时不写谁用谁加
  189. break;
  190. }
  191. return $imageUrl;
  192. }
  193. /**
  194. * 删除oss图片
  195. * @param $url $url为完整路径 http://www......
  196. */
  197. public function checkAndDelOssRemotePic($url = ''){
  198. if (empty($url)) {
  199. return;
  200. }
  201. //获取该文件的路径 去除掉 http网址
  202. $path = substr(parse_url($url, PHP_URL_PATH), 1);
  203. //判断该文件是否存在
  204. if ($this->fileExist($path)) {
  205. $this->fileDelete($path);
  206. }
  207. }
  208. /**
  209. * @param $upType
  210. * @param array $params
  211. * @param $fileName
  212. * @param $ext
  213. * @return array
  214. */
  215. public function getFileNameAndRealContent($upType, array $params, $fileName, $ext){
  216. if ($upType === 'base64') {//base64上传方式
  217. $content = isset($params['content']) ?$params['content']: '';
  218. $rule = "/^(data:\s*image\/(\w+);base64,)/";
  219. if (preg_match($rule, $content, $match)) {
  220. $content = preg_replace($rule, '', $content);
  221. if (!empty($fileName) && empty($ext)) {
  222. $dataImages = [
  223. 'gif' => 'gif',
  224. 'png' => 'png',
  225. 'jpeg' => 'jpg',
  226. 'jpg' => 'jpg',
  227. 'x-icon' => 'ico',
  228. ];
  229. $ext = $dataImages[$match[2]];
  230. $fileName = rtrim($fileName, '.') . '.' . $ext;
  231. }
  232. }
  233. $realContent = base64_decode($content);
  234. } else {//普通文件上传方式
  235. //$content = $this->IJ('content', false, '内容不能为空');
  236. $content = isset($_FILES['content']) ?$_FILES['content']:[];
  237. if (empty($content)) {
  238. throw new \RuntimeException('请选择要上传的文件');
  239. }
  240. if (!empty($fileName) && empty($ext)) {
  241. $imgType = (string)$content['type'];
  242. $imageTypes = [
  243. 'image/gif' => 'gif',
  244. 'image/jng' => 'png',
  245. 'image/jpeg' => 'jpg',
  246. ];
  247. if (!empty($imgType) && in_array($imgType, $imageTypes, true)) {
  248. $ext = $imageTypes[$imgType];
  249. } else if (!empty($content['name'])) {
  250. $ext = pathinfo($content['name'], PATHINFO_EXTENSION);
  251. }
  252. $fileName = rtrim($fileName, '.') . (!empty($ext) ? '.' . $ext : '');
  253. }
  254. $realContent = $content ? file_get_contents($content['tmp_name']) : null;
  255. }
  256. return [$fileName, $realContent];
  257. }
  258. }