ThinkPHP上傳檔案到OSS存儲,檔案下載下傳,擷取檔案過期時間的url,判斷檔案是否存在
先下載下傳相應的代碼包:
通過GIT下載下傳
曆史版本下載下傳
将安裝包放置到: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;
}
}