'其他', self::TYPE_IMAGE => '图片', self::TYPE_VIDEO => '视频', self::TYPE_AUDIO => '音频', ]; public static function getAllType() { return self::$arrType; } /** * @param $tmpPath * @param $filename * @param $mimeType * @return mixed|null * @throws Exception */ public function getFileUrl($tmpPath, $filename, $mimeType) { // 控制频率 $objLock = new Lock('file_upload', 300, 50); $objLock->lock(User::getUserId()); if (!file_exists($tmpPath)) { throw new Exception('file not exists', CODE_PARAM_ERROR); } $md5 = md5_file($tmpPath); $row = $this->objTable->getRow(['id' => $md5]); if ($row) { return self::_fixUrl($row['url']); } $ext = pathinfo($filename, PATHINFO_EXTENSION); $type = self::getType($mimeType); $filename = self::getFileName($md5, $tmpPath, $type, $ext); $url = self::s3PutObject($tmpPath, $filename, $mimeType); if ($url) { $this->objTable->addObject([ 'id' => $md5, 'url' => $url, 'type' => $type, ]); } return $url; } private static function getFileName($md5, $path, $type, $ext = '') { $str = ''; $len = filesize($path); if ($type == self::TYPE_IMAGE) { $arr = getimagesize($path); $str = sprintf('%s_%s_%s', $md5, "size{$arr[0]}x{$arr[1]}", "len{$len}"); } else { $str = sprintf('%s_%s', $md5, "len{$len}"); } $ext && $str .= ".{$ext}"; return $str; } /** * 获取类型 * @author solu * @param $mineType * @return int */ public static function getType($mineType) { if (false !== strpos($mineType, 'image')) { return self::TYPE_IMAGE; } elseif (false !== strpos($mineType, 'video')) { return self::TYPE_VIDEO; } elseif (false !== strpos($mineType, 'audio')) { return self::TYPE_AUDIO; } return self::TYPE_OTHER; } /** * 上传文件 * @author solu * @param $path * @param $name * @return string * @throws Exception */ private static function s3PutObject($path, $name, $mime) { $s3 = new S3Client([ 'version' => 'latest', 'region' => 'ap-northeast-1', 'scheme' => 'http', 'credentials' => [ 'key' => AWS_ACCESS_KEY, 'secret' => AWS_SECRET_KEY, ], ]); $result = $s3->putObject([ 'Bucket' => BUCKET_MEE, 'Key' => $name, 'CacheControl' => 'max-age=8640000', // 前端缓存100天 'Body' => fopen($path, 'r'), 'ACL' => 'public-read', 'ContentType' => $mime, ]); $url = $result->get('ObjectURL'); if (!$url) { throw new Exception('upload to s3 error', CODE_NORMAL_ERROR); } return self::_fixUrl($url); } /** * 转换url * @author solu * @param $url * @return string */ private static function _fixUrl($url) { if (strpos($url, CDN_HOST) === false) { $pos = strrpos($url, '/') + 1; $path = substr($url, $pos); return sprintf('https://%s/%s', CDN_HOST, $path); } return $url; } }