OSS雲文件列舉分頁功能的解決方法

前言:

    目前項目開發中上傳功能很多都是使用雲存儲,其好處太多這裏就不列舉了。但是在上傳成功後,有些功能場景下需要對存儲桶內的文件進行管理。自然把歷史的文件列表展示出來就很有必要了。然後有列表就有分頁,雲存儲又不像本地存儲直接讀文件夾就可以,所以我想了兩種方法來解決。

 

方法:

1. 將上傳的文件返回的地址都存到數據庫中,取列表就分頁的讀表返回。

2. 使用OSS文檔的文件列舉方法,好處是不用建表等等,所以下面以這種方式演示。

 

說明:

        Oss的SDK中提供一個方法listObjects,接收兩個參數($bucket, $options)。分別表示存儲桶名,基本參數集。$options是個數組,裏面又有$prefix,$delimiter,$nextMarker,$maxkeys,參數描述見如下。

        $prefix是自己在存儲桶下存放文件的文件夾路徑,做分頁最主要的是$nextMarker,$maxkeys這兩個參數。一個是文件的起點就相當於分頁start,一個是每次列舉的最大個數就相當於page_size。

 

思路:

     實現這個分頁是不帶頁碼下拉式加載,所以不存在可以點擊返回上一頁,主要從$nextMarker,$maxkeys開始。

    1. getNextMarker()方法獲取上一次列舉文件的標識,沒有爲空竄,有則返回上一次列表最後的那個文件路徑。

    2. 將返回的標識存入緩存中,每次接口請求進來從緩存中讀取一下上一次的文件標識。

    3. 將標識傳入listObjects方法中$options參數的$nextMarker。就可以以上一次標識爲起點列舉後面的列表。

    4. 自定義一參數,如$page,(爲0,$nextMarker則不取緩存直接傳入空竄標識;下拉時則page累加傳入緩存標識)。這樣就可在接口請求時從最開始列舉Oss文件。

 

代碼實現:

1. 業務接口方法。

/*
     * 列舉公用(獲取圖片列表/獲取文件列表)
     * @access private
     * @return array
     * */
    private function getList($page = 0 , $dirname)
    {
        list($proctol,$domain) = explode("//", $this->oss->config['EndPoint']);         // Oss對外域名

        /*獲取配置項分頁頁碼,判斷頁數*/
        if (!empty($this->ueconfig) && is_array($this->ueconfig)) {
            $pageSize = 20;
        }
        
        // 文件起點標識
        $marker = "";
        if($page > 0) {
            $marker = Cache::store('redis')->get($this->config['bucket']."-".$dirname."maker");
        }
        
        // 獲取配置文件中的頁碼
        $pageSize = $this->ueconfig['imageManagerListSize'];
        //$pageSize = 2;
        
        // 調用封裝的Oss文件列舉方法
        $res = $this->oss->listBuckets($this->config['bucket'],$dirname,$pageSize,$marker);

        $ret = [];
        if($res['code'] == 1) {
            foreach ($res['data']['obj']->getObjectList() as $key => $value) {
                //$ret[] = $proctol."//".$this->config['bucket'].".".$domain."/".$value->getKey();
                array_unshift($ret,$proctol."//".$this->config['bucket'].".".$domain."/".$value->getKey());
            }

            if(!$res['data']['next_marker']) {
                $marker = explode(".com/",$ret[0])[1];
            } else {
                $marker = $res['data']['next_marker'];
            }

            // 標識存入緩存
            Cache::store('redis')->set($this->config['bucket']."-".$dirname."maker",$marker);
        }

        return $ret;
    }

 

2. Oss文件列舉封裝方法。

/*
     * 列舉文件
     * @access public
     * @add: bqs
     * @praam: string $bucket 存儲桶名
     * @param: string $prefix 文件路徑
     * @param: int $page 開始頁
     * @param: int $maker 分頁標識
     * @return: array
     * */
    public function listBuckets($bucket = "hhbusiness", $prefix = "", $pagesize = 20, $maker = "")
    {
        $config = $this->config;
        $res['code'] = 1;
        $res['message'] = '';
        $res['data'] = "";
        try {
            $ossClient = new OssClient($config['AccessKeyID'], $config['AccessKeySecret'], $config['EndPoint']);

            //$prefix = 'article/uploadimage/';
            $delimiter = '/';
            $nextMarker = "";
            //$maxkeys = 1;

            $options = array(
                'delimiter' => $delimiter,
                'prefix' => $prefix,
                'max-keys' => $pagesize,
                'marker' => $maker,
            );
            $result['obj'] = $ossClient->listObjects($bucket, $options);

            $result['next_marker'] = $result['obj']->getNextMarker();

            // 沒有值
            if ($result['obj']->getIsTruncated() !== "true") {
                //break;
            }

            $res['code'] = 1;
            $res['data'] = $result;

        } catch (OssException $e) {
            $res['code'] = 0;
            $res['message'] = $e->getMessage();
        }
        return $res;
    }

 

公衆號回覆 “Oss列舉” 獲取完整的示例代碼。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章