Appearance
OSS
使用阿里云 OSS 保存静态文件,可以减少网站服务器压力,并可加快网页显示。阿里云也提供了比较系统的 OSS 学习路径 便于学习使用。下面斑马兽快速带你使用 OSS。
服务配置
首先访问阿里云 OSS 服务,并添加 Bucket。
- 如果公开访问的网站静态文件可以设置权限为「公共读」,
- 建议 oss 使用 private 私有模式,结合 CDN 保存静态资源,这样费用更低,速度也快
程序编码
下面来安装阿里云提供的PHP SDK快速将 OSS 功能集成到你的项目中
安装配置
composer require aliyuncs/oss-sdk-php
创建 App\Services\OssService
oss 服务文件,修改App\ProvidersAppServiceProvider
将服务文件注册到项目中
class AppServiceProvider extends ServiceProvider
{
public $singletons = [
"oss" => OssService::class
];
...
}
上传服务
接下来实现 OssService 代码,用于 OSS 上传文件与创建 bucket
<?php
namespace App\Services;
use Illuminate\Support\Facades\Auth;
use OSS\OssClient;
use OSS\Core\OssException;
use OSS\Credentials\StaticCredentialsProvider;
//阿里云OSS服务
class OssService
{
protected $ossProvider;
protected $ossClient;
protected $bucket;
public function __construct()
{
$this->init();
}
//初始化OSS实例
private function init()
{
//阿里云 bucket
$this->bucket = config('bm.admin.aliyun_oss_bucket');
//阿里云OSS Provider用于生成 ossclient 配置
$this->ossProvider = new StaticCredentialsProvider(config('bm.admin.aliyun_key'), config('bm.admin.aliyun_secret'));
$config = array(
"provider" => $this->ossProvider,
"endpoint" => config('bm.admin.aliyun_oss_endpoint'),
);
//生成oss客户端用于使用 oss 功能
$this->ossClient = new OssClient($config);
}
/**
* 上传文件到 oss
*
* @param string $object oss 保存的文件路径
* @param string $content 文件内容
* @param array $options 上传选项
*/
public function upload(string $object, string $content, array $options = [])
{
$file = request('file');
try {
//上传文件到 oss
$response = $this->ossClient->putObject($this->bucket, $object, $content, $options);
// oss 返回的链接
$url = $response['oss-request-url'];
//如果配置了 cdn 域名,则返回 cdn 链接
if (config('bm.admin.aliyun_cdn_domain')) {
$url = config('bm.admin.aliyun_cdn_domain') . preg_replace('/https?:\/\/.+?(?=\/)/is', '', $response['oss-request-url']);;
}
//将上传文件信息保存到数据库
return Auth::user()->uploads()->create([
'url' => $url,
'name' => $file->getClientOriginalName(),
'size' => $file->getSize(),
'extension' => $file->getClientOriginalExtension(),
'mime' => $file->getMimeType()
]);
} catch (OssException $e) {
abort(400, $e->getMessage());
}
}
//创建OSS储存块
public function createBucket()
{
try {
$this->ossClient->createBucket(config('bm.admin.aliyun_oss_bucket'));
} catch (OssException $e) {
abort(400, 'OSS bucket创建失败!' . $e->getMessage());
}
}
/**
* cdn资源签名
* @param string $path 文件地址
*/
public function cdnSign(string $path)
{
//如果你使用 oss 桌面端软件复制的链接,需要把OSSAccessKeyId字符串删除掉
// $path = preg_replace('/\?OSSAccessKeyId=.+/i', '', $path);
if (empty($path)) return;
$domain = config('bm.admin.aliyun_cdn_domain');
$key = config('bm.admin.aliyun_cdn_key');
$filename = preg_replace('/https?:\/\/.+?(?=\/)/is', '', $path);
$time = strtotime("+20 minutes");
$sstring = $filename . "-" . $time . "-0-0-" . $key;
$auth_key = "auth_key=" . $time . "-0-0-" . md5($sstring);
return $domain . $filename . "?" . $auth_key;
}
}
控制器
下面是在控制器中使用 oss 处理视频上传
//更新视频
class UpdateVideoController extends Controller implements HasMiddleware
{
public static function middleware()
{
return [new Middleware('auth:sanctum', except: [])];
}
...
//上传视频
public function uploadVideo(Request $request, Chapter $chapter)
{
$size = config('bm.admin.upload_file_size') * 1024;
$request->validate(['file' => ['required', 'file', "max:{$size}"]]);
return app('oss')->upload($this->dir . '/' . $this->file->hashName(), file_get_contents($this->file));
}
}
前端组件
文件上传的前端组件,我已经写了文档,你可以在文档库中查看。