Laravel 阿里云OSS图片上传
OSS对象存储 ( Object Storage Service, 简称 OSS ) , 它是阿里云对外提供的海量、安全和高可靠的云存储服务。大家可以把自己网站的资源存上面加快自己网站速度。
本文使用johnlui/aliyun-oss这个组件,用法简单易懂,但是还是有部分地方需要注意。
安装
composer require "johnlui/aliyun-oss"
配置
组件下载完成之后, 在 app/config 下面新建一个 oss.php 文件然后在添加配置:
return [
/**
* 经典网络 or VPC
*/
'networkType' => env('OSS_NET_WORK_TYPE','经典网络'),
/**
* 城市名称:
* 经典网络下可选:杭州、上海、青岛、北京、张家口、深圳、香港、硅谷、弗吉尼亚、新加坡、悉尼、日本、法兰克福、迪拜
* VPC 网络下可选:杭州、上海、青岛、北京、张家口、深圳、硅谷、弗吉尼亚、新加坡、悉尼、日本、法兰克福、迪拜
*/
'city' => env('OSS_CITY','深圳'),
'AccessKeyId' => env('OSS_ACCESS_KEY_ID',''),
'AccessKeySecret' => env('OSS_ACCESS_KEY_SECRET',''),
'bucketName' => env('OSS_BUCKET_NAME'),
'ossDomain' => env('OSS_DOMAIN'),//OSS绑定域名
];
然后在 .env 文件里面把配置信息都填上。
构建 Service 文件
<?php
namespace App\Library\Oss;
use JohnLui\AliyunOSS;
use Exception;
use DateTime;
class OSS
{
private $ossClient;
/**
* 私有初始化 API,非 API,不用关注
* @param boolean 是否使用内网
*/
public function __construct($isInternal = false)
{
if (config('oss.networkType') == 'VPC' && !$isInternal) {
throw new Exception("VPC 网络下不提供外网上传、下载等功能");
}
$this->ossClient = AliyunOSS::boot(
config('oss.city'),
config('oss.networkType'),
$isInternal,
config('oss.AccessKeyId'),
config('oss.AccessKeySecret')
);
}
/**
* 使用外网上传文件
* @param string bucket名称
* @param string 上传之后的 OSS object 名称
* @param string 上传文件路径
* @return boolean 上传是否成功
*/
public static function publicUpload($bucketName, $ossKey, $filePath, $options = [])
{
$oss = new OSS();
$oss->ossClient->setBucket($bucketName);
return $oss->ossClient->uploadFile($ossKey, $filePath, $options);
}
/**
* 使用阿里云内网上传文件
* @param string bucket名称
* @param string 上传之后的 OSS object 名称
* @param string 上传文件路径
* @return boolean 上传是否成功
*/
public static function privateUpload($bucketName, $ossKey, $filePath, $options = [])
{
$oss = new OSS(true);
$oss->ossClient->setBucket($bucketName);
return $oss->ossClient->uploadFile($ossKey, $filePath, $options);
}
/**
* 使用外网直接上传变量内容
* @param string bucket名称
* @param string 上传之后的 OSS object 名称
* @param string 上传的变量
* @return boolean 上传是否成功
*/
public static function publicUploadContent($bucketName, $ossKey, $content, $options = [])
{
$oss = new OSS();
$oss->ossClient->setBucket($bucketName);
return $oss->ossClient->uploadContent($ossKey, $content, $options);
}
/**
* 使用阿里云内网直接上传变量内容
* @param string bucket名称
* @param string 上传之后的 OSS object 名称
* @param string 上传的变量
* @return boolean 上传是否成功
*/
public static function privateUploadContent($bucketName, $ossKey, $content, $options = [])
{
$oss = new OSS(true);
$oss->ossClient->setBucket($bucketName);
return $oss->ossClient->uploadContent($ossKey, $content, $options);
}
/**
* 使用外网删除文件
* @param string bucket名称
* @param string 目标 OSS object 名称
* @return boolean 删除是否成功
*/
public static function publicDeleteObject($bucketName, $ossKey)
{
$oss = new OSS();
$oss->ossClient->setBucket($bucketName);
return $oss->ossClient->deleteObject($bucketName, $ossKey);
}
/**
* 使用阿里云内网删除文件
* @param string bucket名称
* @param string 目标 OSS object 名称
* @return boolean 删除是否成功
*/
public static function privateDeleteObject($bucketName, $ossKey)
{
$oss = new OSS(true);
$oss->ossClient->setBucket($bucketName);
return $oss->ossClient->deleteObject($bucketName, $ossKey);
}
/**
* -------------------------------------------------
*
*
* 下面不再分公网内网出 API,也不注释了,大家自行体会吧。。。
*
*
* -------------------------------------------------
*/
public function copyObject($sourceBuckt, $sourceKey, $destBucket, $destKey)
{
$oss = new OSS();
return $oss->ossClient->copyObject($sourceBuckt, $sourceKey, $destBucket, $destKey);
}
public function moveObject($sourceBuckt, $sourceKey, $destBucket, $destKey)
{
$oss = new OSS();
return $oss->ossClient->moveObject($sourceBuckt, $sourceKey, $destBucket, $destKey);
}
// 获取公开文件的 URL
public static function getPublicObjectURL($bucketName, $ossKey)
{
if(config('oss.ossDomain')){
return config('oss.ossDomain').'/'.$ossKey;
}
$oss = new OSS();
$oss->ossClient->setBucket($bucketName);
return $oss->ossClient->getPublicUrl($ossKey);
}
// 获取私有文件的URL,并设定过期时间,如 \DateTime('+1 day')
public static function getPrivateObjectURLWithExpireTime($bucketName, $ossKey, DateTime $expire_time)
{
$oss = new OSS();
$oss->ossClient->setBucket($bucketName);
return $oss->ossClient->getUrl($ossKey, $expire_time);
}
public static function createBucket($bucketName)
{
$oss = new OSS();
return $oss->ossClient->createBucket($bucketName);
}
public static function getAllObjectKey($bucketName)
{
$oss = new OSS();
return $oss->ossClient->getAllObjectKey($bucketName);
}
public static function getObjectMeta($bucketName, $ossKey)
{
$oss = new OSS();
return $oss->ossClient->getObjectMeta($bucketName, $ossKey);
}
}
使用
/**
* 文件上传
* @param $file
* @param string $action
* @return array
*/
public function upload($file, $action = 'avatar')
{
if ($file->isValid()) {
$content_type = mime_content_type($file->getRealPath());
$file_name = $action . '/' . time() . rand(10, 99) . '.' . $file->extension();
//头像处理
if ($action == 'avatar') {
$content = Image::make($file)->resize(200, 200)->encode()->encoded;
} else {
$content = file_get_contents($file);
}
$bucket_name = config('oss.bucketName');
OSS::publicUploadContent($bucket_name, $file_name, $content,['ContentType' => $content_type]);//设置HTTP头
//获取公开文件URL
$url = OSS::getPublicObjectURL($bucket_name, $file_name);
//获取私密文件URL
// $expire_time = Carbon::now()->addDay();
// $url = OSS::getPrivateObjectURLWithExpireTime($bucket_name, $file_name,$expire_time);
return compact('url');
} else {
throw new ApiException('文件上传失败', 500);
}
}
以上采用变量内容content上传,也可使用文件路径path进行上传:
$file_path = $file->getRealPath();
Oss::publicUpload($bucket_name, $file_name,$file_path,['ContentType' => $content_type]);
注意
上传的文件若想直接通过URL地址访问,在浏览器预览,需在上传时设置HTTP头:
刚开始我也未修改HTTP头,上传图片后访问链接后,变成图片下载,后来设置HTTP头为:
'Content-Type' => $content_type
试了好久还是不行,后来发现设置如下,就可以了,真是坑啊!!!
'ContentType' => $content_type
其中,文件类型为:
$content_type = mime_content_type($file->getRealPath());
PS
组件github地址:https://github.com/johnlui/AliyunOSS
原作者博客地址:https://lvwenhan.com/laravel/425.html