<?php
namespace service;
use Exception;
use OSS\Core\OssException;
use OSS\OssClient;
use Qiniu\Auth;
use Qiniu\Storage\BucketManager;
use Qiniu\Storage\UploadManager;
use think\facade\Log;
/**
* 系统文件服务
* Class FileService
* @package service
* @author Anyon <zoujingli@qq.com>
* @date 2017/03/15 15:17
*/
class FileService
{
public static function getFileMine($ext, $mine = [])
{
$mines = self::getMines();
foreach (is_string($ext) ? explode(',', $ext) : $ext as $e) {
$mine[] = isset($mines[strtolower($e)]) ? $mines[strtolower($e)] : 'application/octet-stream';
}
return join(',', array_unique($mine));
}
public static function getMines()
{
$mines = cache('all_ext_mine');
if (empty($mines)) {
$content = file_get_contents('http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types');
preg_match_all('#^([^\s]{2,}?)\s+(.+?)$#ism', $content, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
foreach (explode(" ", $match[2]) as $ext) {
$mines[$ext] = $match[1];
}
}
cache('all_ext_mine', $mines);
}
return $mines;
}
public static function getFileUrl($filename, $storage = null)
{
if (self::hasFile($filename, $storage) === false) {
return false;
}
switch (empty($storage) ? sysconf('storage_type') : $storage) {
case 'local':
return self::getBaseUriLocal() . $filename;
case 'qiniu':
return self::getBaseUriQiniu() . $filename;
case 'oss':
return self::getBaseUriOss() . $filename;
}
throw new \think\Exception('未设置存储方式,无法获取到文件对应URL地址');
}
public static function getUploadLocalUrl()
{
return url('@admin/plugs/upload');
}
public static function getUploadQiniuUrl($isClient = true)
{
$region = sysconf('storage_qiniu_region');
$isHttps = !!sysconf('storage_qiniu_is_https');
switch ($region) {
case '华东':
if ($isHttps) {
return $isClient ? 'https://upload.qiniup.com' : 'https://upload.qiniup.com';
}
return $isClient ? 'http://upload.qiniup.com' : 'http://upload.qiniup.com';
case '华北':
if ($isHttps) {
return $isClient ? 'https://upload-z1.qiniup.com' : 'https://up-z1.qiniup.com';
}
return $isClient ? 'http://upload-z1.qiniup.com' : 'http://up-z1.qiniup.com';
case '北美':
if ($isHttps) {
return $isClient ? 'https://upload-na0.qiniup.com' : 'https://up-na0.qiniup.com';
}
return $isClient ? 'http://upload-na0.qiniup.com' : 'http://up-na0.qiniup.com';
case '华南':
if ($isHttps) {
return $isClient ? 'https://upload-z2.qiniup.com' : 'https://up-z2.qiniup.com';
}
return $isClient ? 'http://upload-z2.qiniup.com' : 'http://up-z2.qiniup.com';
default:
throw new \think\Exception('未配置七牛云存储区域');
}
}
public static function getUploadOssUrl()
{
$protocol = request()->isSsl() ? 'https' : 'http';
return "{$protocol}://" . sysconf('storage_oss_domain');
}
public static function getBaseUriLocal()
{
$appRoot = request()->root(true); $uriRoot = preg_match('/\.php$/', $appRoot) ? dirname($appRoot) : $appRoot;
$uriRoot = in_array($uriRoot, ['/', '\\']) ? '' : $uriRoot;
return "{$uriRoot}/static/upload/";
}
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 default:
throw new \think\Exception('未设置七牛云文件地址协议');
}
}
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 default:
throw new \think\Exception('未设置阿里云文件地址协议');
}
}
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 hasFile($filename, $storage = null)
{
switch (empty($storage) ? sysconf('storage_type') : $storage) {
case 'local':
return file_exists(env('root_path') . 'static/upload/' . $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;
}
public static function readFile($filename, $storage = null)
{
switch (empty($storage) ? sysconf('storage_type') : $storage) {
case 'local':
$file = env('root_path') . 'static/upload/' . $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('未配置读取文件的存储方法');
}
}
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);
}
public static function local($filename, $content)
{
try {
$realfile = env('root_path') . 'static/upload/' . $filename;
!file_exists(dirname($realfile)) && mkdir(dirname($realfile), 0755, true);
if (file_put_contents($realfile, $content)) {
$url = pathinfo(request()->baseFile(true), PATHINFO_DIRNAME) . '/static/upload/' . $filename;
return ['file' => $realfile, 'hash' => md5_file($realfile), 'key' => "static/upload/{$filename}", 'url' => $url];
}
} catch (Exception $err) {
Log::error('本地文件存储失败, ' . $err->getMessage());
}
return null;
}
public static function qiniu($filename, $content)
{
$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;
}
public static function oss($filename, $content)
{
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 = }
return ['file' => $filename, 'hash' => $result['content-md5'], 'key' => $filename, 'url' => $site_url];
} catch (OssException $err) {
Log::error('阿里云OSS文件上传失败, ' . $err->getMessage());
}
return null;
}
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') . 'static/upload/' . $filename;
return ['file' => $realfile, 'hash' => md5_file($realfile), 'key' => "static/upload/{$filename}", 'url' => $siteUrl];
}
return self::local($filename, file_get_contents($url));
} catch (\Exception $e) {
Log::error("FileService 文件下载失败 [ {$url} ] " . $e->getMessage());
}
return ['url' => $url];
}
}