isSsl() ? 'https' : 'http'; return "{$protocol}://" . sysconf('storage_oss_domain'); } /** * 获取服务器URL前缀 * @return string */ public static function getBaseUriLocal() { $appRoot = request()->root(true); // 去掉参数 true 将获得相对地址 $uriRoot = preg_match('/\.php$/', $appRoot) ? dirname($appRoot) : $appRoot; $uriRoot = in_array($uriRoot, ['/', '\\']) ? '' : $uriRoot; return "{$uriRoot}/"; } /** * 获取七牛云URL前缀 * @return string * @throws \think\Exception * @throws \think\exception\PDOException */ public static function getBaseUriQiniu() { switch (strtolower(sysconf('storage_qiniu_is_https'))) { case 'https': return 'https://' . sysconf('storage_qiniu_domain') . '/'; case 'http': return 'http://' . sysconf('storage_qiniu_domain') . '/'; case 'auto': return '//' . sysconf('storage_qiniu_domain') . '/'; default: throw new \think\Exception('未设置七牛云文件地址协议'); } } /** * 获取阿里云对象存储URL前缀 * @return string * @throws \think\Exception * @throws \think\exception\PDOException */ public static function getBaseUriOss() { switch (strtolower(sysconf('storage_oss_is_https'))) { case 'https': return 'https://' . sysconf('storage_oss_domain') . '/'; case 'http': return 'http://' . sysconf('storage_oss_domain') . '/'; case 'auto': return '//' . sysconf('storage_oss_domain') . '/'; default: throw new \think\Exception('未设置阿里云文件地址协议'); } } /** * 获取文件相对名称 * @param string $local_url 文件标识 * @param string $ext 文件后缀 * @param string $pre 文件前缀(若有值需要以/结尾) * @return string */ public static function getFileName($local_url, $ext = '', $pre = '') { empty($ext) && $ext = strtolower(pathinfo($local_url, 4)); return $pre . join('/', str_split(md5($local_url), 16)) . '.' . ($ext ? $ext : 'tmp'); } public static function removeSuffix($fileName) { return basename($fileName, "." . substr(strrchr($fileName, '.'), 1)); } /** * 检查文件是否已经存在 * @param string $filename * @param string|null $storage * @return bool * @throws OssException * @throws \think\Exception * @throws \think\exception\PDOException */ public static function hasFile($filename, $storage = null) { switch (empty($storage) ? sysconf('storage_type') : $storage) { case 'local': return file_exists(env('root_path') . $filename); case 'qiniu': $auth = new Auth(sysconf('storage_qiniu_access_key'), sysconf('storage_qiniu_secret_key')); $bucketMgr = new BucketManager($auth); list($ret, $err) = $bucketMgr->stat(sysconf('storage_qiniu_bucket'), $filename); return $err === null; case 'oss': $ossClient = new OssClient(sysconf('storage_oss_keyid'), sysconf('storage_oss_secret'), self::getBaseUriOss(), true); return $ossClient->doesObjectExist(sysconf('storage_oss_bucket'), $filename); } return false; } /** * 根据Key读取文件内容 * @param string $filename * @param string|null $storage * @return string|null * @throws \think\Exception * @throws \think\exception\PDOException * @throws OssException */ public static function readFile($filename, $storage = null) { switch (empty($storage) ? sysconf('storage_type') : $storage) { case 'local': $file = env('root_path') . config('upload.base_path') . $filename; return file_exists($file) ? file_get_contents($file) : ''; case 'qiniu': $auth = new Auth(sysconf('storage_qiniu_access_key'), sysconf('storage_qiniu_secret_key')); return file_get_contents($auth->privateDownloadUrl(self::getBaseUriQiniu() . $filename)); case 'oss': $ossClient = new OssClient(sysconf('storage_oss_keyid'), sysconf('storage_oss_secret'), self::getBaseUriOss(), true); return $ossClient->getObject(sysconf('storage_oss_bucket'), $filename); default: throw new \think\Exception('未配置读取文件的存储方法'); } } /** * 根据当前配置存储文件 * @param string $filename * @param string $content * @param string|null $file_storage * @return array|false * @throws \think\Exception * @throws \think\exception\PDOException */ public static function save($filename, $content, $file_storage = null) { $type = empty($file_storage) ? sysconf('storage_type') : $file_storage; if (!method_exists(__CLASS__, $type)) { Log::error("保存存储失败,调用{$type}存储引擎不存在!"); return false; } return self::$type($filename, $content); } /** * 文件储存在本地 * @param string $filename * @param string $content * @return array|null */ public static function local($filename, $content, $append = false) { try { $realfile = env('root_path') . $filename; !file_exists(dirname($realfile)) && mkdir(dirname($realfile), 0755, true); if (file_put_contents($realfile, $content, $append ? FILE_APPEND : 0)) { $url = pathinfo(request()->baseFile(true), PATHINFO_DIRNAME) . '/' . $filename; return ['file' => $realfile, 'hash' => md5_file($realfile), 'key' => "{$filename}", 'url' => $url]; } } catch (Exception $err) { Log::error('本地文件存储失败, ' . $err->getMessage()); } return null; } /** * 七牛云存储 * @param string $filename * @param string $content * @return array|null * @throws \think\Exception * @throws \think\exception\PDOException */ public static function qiniu($filename, $content, $append = false) { $auth = new Auth(sysconf('storage_qiniu_access_key'), sysconf('storage_qiniu_secret_key')); $token = $auth->uploadToken(sysconf('storage_qiniu_bucket')); $uploadMgr = new UploadManager(); list($result, $err) = $uploadMgr->put($token, $filename, $content); if ($err !== null) { Log::error('七牛云文件上传失败, ' . $err->getMessage()); return null; } $result['file'] = $filename; $result['url'] = self::getBaseUriQiniu() . $filename; return $result; } /** * 阿里云OSS * @param string $filename * @param string $content * @return array|null * @throws \think\Exception * @throws \think\exception\PDOException */ public static function oss($filename, $content, $append = false) { try { $endpoint = 'http://' . sysconf('storage_oss_domain'); $ossClient = new OssClient(sysconf('storage_oss_keyid'), sysconf('storage_oss_secret'), $endpoint, true); $result = $ossClient->putObject(sysconf('storage_oss_bucket'), $filename, $content); $baseUrl = explode('://', $result['oss-request-url'])[1]; if (strtolower(sysconf('storage_oss_is_https')) === 'http') { $site_url = "http://{$baseUrl}"; } elseif (strtolower(sysconf('storage_oss_is_https')) === 'https') { $site_url = "https://{$baseUrl}"; } else { $site_url = "//{$baseUrl}"; } return ['file' => $filename, 'hash' => $result['content-md5'], 'key' => $filename, 'url' => $site_url]; } catch (OssException $err) { Log::error('阿里云OSS文件上传失败, ' . $err->getMessage()); } return null; } /** * 下载文件到本地 * @param string $url 文件URL地址 * @param bool $isForce 是否强制重新下载文件 * @return array */ public static function download($url, $isForce = false) { try { $filename = self::getFileName($url, '', 'download/'); if (false === $isForce && ($siteUrl = self::getFileUrl($filename, 'local'))) { $realfile = env('root_path') . config('upload.base_path') . $filename; return ['file' => $realfile, 'hash' => md5_file($realfile), 'key' => config('upload.base_path') . "{$filename}", 'url' => $siteUrl]; } return self::local($filename, file_get_contents($url)); } catch (\Exception $e) { Log::error("FileService 文件下载失败 [ {$url} ] " . $e->getMessage()); } return ['url' => $url]; } }