天天看點

ThinkPHP上傳檔案到OSS存儲,檔案下載下傳,擷取檔案過期時間的url,判斷檔案是否存在

ThinkPHP上傳檔案到OSS存儲,檔案下載下傳,擷取檔案過期時間的url,判斷檔案是否存在

先下載下傳相應的代碼包:

通過GIT下載下傳

曆史版本下載下傳

将安裝包放置到:thinkphpOSS\ThinkPHP\Library\Vendor下面

ThinkPHP上傳檔案到OSS存儲,檔案下載下傳,擷取檔案過期時間的url,判斷檔案是否存在

我是直接在代碼中配置相關資訊,是以并沒有配置相關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;
        }
    }
           

如果哪位大佬發現有錯誤,或者有更好的辦法,請聯系我,謝謝!