ThinkPHP上传文件到OSS存储,文件下载,获取文件过期时间的url,判断文件是否存在
将安装包放置到:thinkphpOSS\ThinkPHP\Library\Vendor下面
我是直接在代码中配置相关信息,所以并没有配置相关config.php
新建一个控制器,先进入H5页面,然后在H5页面进行上传图片,H5页面写的很简单,直接上代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</br></br></br>
<form enctype="multipart/form-data" method="post" name="fileinfo" action="{:U('Home/oss/image')}">
<table>
<tr>
<td>上传图片:</td>
<td><input type="file" name="image" accept="*"></td><td colspan="2"><input type="submit" value="上传"></td>
</tr>
</table>
</form>
</body>
</html>
配置OSS这里就跳过,现在默认已经获取到相应数据,如:
'ACCESS_KEY_ID' => '', //从OSS获得的AccessKeyId
'ACCESS_KEY_SECRET' => '', //从OSS获得的AccessKeySecret
'ENDPOINT' => '', //您选定的OSS数据中心访问域名,例如oss-cn-hangzhou.aliyuncs.com
'BUCKET'=>''//目录
下面是控制器代码:
<?php
namespace Home\Controller;
use Think\Controller;
use OSS\OssClient;//导入上传的方法
use OSS\Core\OssException;//导入上传的方法
use think\Image;//导入上传的方法
class OssController extends Controller
{
public function index(){
$this->display('index/index');
}
/**
* 上传图片
* 需传入参数为:本地图片的地址
* 返回成功或失败
* 需要获取的值,都在方法头部的公共方法中获取,图片数据直接让前端传值即可
**/
public function save_image(){//上传图片
header('Content-Type: text/html; charset=utf-8');
$bucket= $_REQUEST['BUCKET'];// 存储空间名称,需要前端传递过来
$dir = $_REQUEST['dir'];//放置到OSS的哪个文件夹下,需要前端传递过来
$ip = $_SERVER["REMOTE_ADDR"];//获取当前IP地址,判断是否有权限访问
$array_ip = [
'127.0.0.1'
];
if(!in_array($ip,$array_ip)){
$back['msg']='此用户不允许上传';
$back['status'] = '-1';
$back['data'] = '';
return $back;
}
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
$file = $_FILES['image'];//获取图片文件
/*$type = $file['type'];//如需判断类型,则打开此代码
$allow_type = ['image/jpg', 'image/jpeg', 'image/gif', 'image/bmp', 'image/png'];/*判断图片格式*/
if (!in_array($type, $allow_type)) {//判断图片格式是否正确
$back['msg']='文件格式不在允许范围内哦';
$back['status'] = '-1';
$back['data'] = '';
return $back;
}*/
$setsize = 1048576;//文件最大限制1M
$size = $file['size'];//获取图片大小
if($size > $setsize ){
$back['msg']='文件超过了1M';
$back['status'] = '-1';
$back['data'] = '';
return $back;
}
$OSS = $this->config();//获取控制器头部公共方法中的数据参数
$filePath = $file['tmp_name'];//获取图片名称
$accessKeyId = $OSS['ACCESS_KEY_ID'];//获取OSS的指定配置参数
$accessKeySecret = $OSS['ACCESS_KEY_SECRET'];//获取OSS的指定配置参数
$endpoint = $OSS['ENDPOINT'];// Endpoint以杭州为例,其它Region请按实际情况填写。
$object = $dir.'/'.date('YmdHis',time()).mt_rand(1000,9999).$file['name'];// 文件路径和名称
try{
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
$ossClient->uploadFile($bucket, $object, $filePath);
$url = $bucket.'.'.$endpoint.'/'.$object;//返回的url访问地址
$back['status'] = '200';
$back['msg'] = '成功';
$back['data'] = $url;
return $back;
} catch(OssException $e) {
$back['status'] = '-1';
$back['msg'] = '失败';
$back['data'] = '';
return $back;
}
}
如果访问权限设置为私有属性,不能随便查看,那么可以生成临时的url进行查看,在规定的时间内可以查看,超过规定时间则不能查看,直接上代码
生成的url是这样的:http://bucket.oss-cn-shanghai.aliyuncs.com/dir/1.txt?OSSAccessKeyId=****************&Expires=1554718994&Signature=ma7mI1Btghbgttj%2RFEKIT4p4lE%3D
bucket为文件的BUCKET目录,Expires为过期时间,Signature为随机编码
- 以下代码直接从url中获取bucket,不用传值,只需要文件的url地址和过期时间即可。
/**
* 需要获取的值,都在方法头部获取,直接让前端传值即可
*/
public function file(){//访问私有文件时,获取带过期时间的URL地址
header('Content-Type: text/html; charset=utf-8');
$timeout = $_REQUEST['TIMEOUT'] ? $_REQUEST['TIMEOUT'] : '60'; //过期时间,如果没传,则默认60秒
$url = trim($_REQUEST['url']);//要访问的文件链接
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
$OSS = [
'ACCESS_KEY_ID' => '', //从OSS获得的AccessKeyId
'ACCESS_KEY_SECRET' => '', //从OSS获得的AccessKeySecret
'ENDPOINT' => '', //您选定的OSS数据中心访问域名,例如oss-cn-hangzhou.aliyuncs.com
'TIMEOUT'=> 60//过期时间,最大为
];
$accessKeyId = $OSS['ACCESS_KEY_ID'];
$accessKeySecret = $OSS['ACCESS_KEY_SECRET'];
$endpoint = $OSS['ENDPOINT'];// Endpoint以杭州为例,其它Region请按实际情况填写。
$is_existence = $this->is_existence($url);//判断文件是否存在,这个方法在下面代码中会提到,直接调用即可,如果不需要注释此行和下面判断的代码即可
if(!$is_existence){
$back['status'] = '-1';
$back['msg'] = '没有此文件!';
$back['data'] = '';
return $back;
}
$b = strpos($url,'://');//对url地址进行截取,获取bucket值,也可以直接从头部方法调用
$d = strpos($url,'.oss');
$bucket = substr($url,$b+3,$d-7);// 存储空间名称
$a = strpos($url,'com/');
$object = substr($url,$a+4);//对url地址进行截取,获取object值,也可以直接从头部方法调用
try{
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
$token = $ossClient->signUrl($bucket, $object, $timeout);
$back['status'] = '200';
$back['msg'] = '成功';
$back['data'] = $token;
return $back;
} catch(OssException $e) {
$back['status'] = '-1';
$back['msg'] = '失败';
$back['data'] = '';
return $back;
}
}
下载OSS中的文件
/**
* 下载文件
* 返回下载的位置
* 需传递的参数有:文件的url地址($url),
* 如果需要水印,则传入$txt,程序会自动生成带有水印的图片(水印默认位置默认为右下角,字体为13,如需修正,请自行修改代码)
* 以下代码直接从url中获取bucket,不用传值,只需要文件的url地址即可
* 需要获取的值,都在方法头部获取,直接让前端传值即可
**/
public function download_image(){//下载文件
header('Content-Type: text/html; charset=utf-8');
$url = trim($_REQUEST['url']);//要访问的文件链接
$localfile = str_replace("\\",'/',$_REQUEST['localfile'])."/".$file_name.$type;//下载到本地的地址
$txt = $_REQUEST['txt'];//水印信息
$ip = $_SERVER["REMOTE_ADDR"];
$array_ip = [
'127.0.0.1'
];
if(!in_array($ip,$array_ip)){
$back['msg']='此用户不允许下载!';
$back['status'] = '-1';
$back['data'] = '';
return $back;
}
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
$OSS = $this->config();
$accessKeyId = $OSS['ACCESS_KEY_ID'];
$accessKeySecret = $OSS['ACCESS_KEY_SECRET'];
$endpoint = $OSS['ENDPOINT'];// Endpoint以杭州为例,其它Region请按实际情况填写。
$is_existence = $this->is_existence($url);//判断文件是否存在,这个方法在下面代码中会提到,直接调用即可
if(!$is_existence){
$back['status'] = '-1';
$back['msg'] = '没有此文件!';
$back['data'] = '';
return $back;
}
$b = strpos($url,'://');//对url地址进行截取,获取bucket值
$d = strpos($url,'.oss');
$bucket = substr($url,$b+3,$d-7);// 存储空间名称
$type_count = strrpos($url,'.');//对url地址进行截取,获取文件类型
$type = substr($url,$type_count);//文件后缀
$a = strpos($url,'.com/');
$object = substr($url,$a+5);//对url地址进行截取,获取OSS文件存储地址
$file_name = date('YmdHis',time());//文件名称
$options = array(
OssClient::OSS_FILE_DOWNLOAD => $localfile
);
if(!empty($txt)){//如果有水印信息,则添加水印
$bas = base64_encode($txt);
$jian = str_replace('+','-',$bas);//加号改为减号
$gang = str_replace('/','_',$jian);//斜杠改为下划线
$strpos = strpos($gang,'=');
$bace = "text_".$gang;
if(!empty($strpos)){
$bace = "text_".substr($gang,0,$strpos);//删除等号,并拼接水印信息
}
$watermark = [OssClient::OSS_PROCESS => 'image/watermark,'.$bace.",t_80,g_se,size_13" ];
$options = array_merge($options,$watermark);
}
try{
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
$ossClient->getObject($bucket, $object, $options);//无返回值
$back['status'] = '200';
$back['msg'] = '成功';
$back['data'] = $localfile;//返回保存的文件路径
return $back;
} catch(OssException $e) {
$back['status'] = '-1';
$back['msg'] = '失败';
$back['data'] = '';
return $back;
}
}
判断文件是否存在
/**
* 判断文件是否存在
* 需传递的参数有:文件的url地址($url)
* 返回true或false
* *需要获取的值,都在方法头部获取,直接让前端传值即可
**/
public function is_existence($url = null){
$url = trim($url ? $url : $_REQUEST['url']);//要访问的文件链接地址,如:http://image.oss-cn-hangzhou.aliyuncs.com/img/1.jpg
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
$OSS = [
'ACCESS_KEY_ID' => '', //从OSS获得的AccessKeyId
'ACCESS_KEY_SECRET' => '', //从OSS获得的AccessKeySecret
'ENDPOINT' => '', //您选定的OSS数据中心访问域名,例如oss-cn-hangzhou.aliyuncs.com
'TIMEOUT'=> 60//过期时间
];
$accessKeyId = $OSS['ACCESS_KEY_ID'];
$accessKeySecret = $OSS['ACCESS_KEY_SECRET'];
$endpoint = $OSS['ENDPOINT'];// Endpoint以杭州为例,其它Region请按实际情况填写。
if(empty($url)){
$back['status'] = '-1';
$back['msg'] = 'url地址无效';
$back['data'] = '';
return $back;
}
$b = strpos($url,'://');
$d = strpos($url,'.oss');
$bucket = substr($url,$b+3,$d-7);// 存储空间名称
$a = strpos($url,'.com/');
$object = substr($url,$a+5);//OSS文件存储地址
try{
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
$exist = $ossClient->doesObjectExist($bucket, $object);
return $exist;
} catch(OssException $e) {
$exist = false;
return $exist;
}
}