百度云对象存储BOS和文档服务DOC

原创
2017/12/01 10:17
阅读数 2.3K

要写这个是因为有一个同学要搞在线浏览文档的功能,所以就让我看看。就用自己的百度云看了一下,结果自己还充了一块钱,滑稽脸.jpg。 先自己手动建了一个bucket看自己能不能实现上传到BOS 地域一定是华北-北京 因为是做的PHP要看的自然也是PHP的SDK了https://cloud.baidu.com/doc/BOS/PHP-SDK.html 把SDK的包下下来解压放到自己准备好的路径里面,我是用ThinkPHP写的。 SDK安装包 为了看到里面的结构我还是把phar文件解压了一份。 跟着文档首先就是拿到自己的ak和sk两个参数,这个在自己账号的安全认证页面也是有的 获取参数 根据文档创建bucket,然后获取对应的参数

/*
     * 生成bucket 参数 $BOS_TEST_CONFIG
     * */
    public function sampleConf(){
        $BOS_TEST_CONFIG = array(
            'credentials' => array(
                'accessKeyId' => $this->ak,
                'secretAccessKey' => $this->sk,
            ),
            'stsEndpoint' => 'sts.bj.baidubce.com',
            'protocol' => 'http',
        );
        $client = new StsClient($BOS_TEST_CONFIG);
        $request =
            array(
                'acl' => '', //用户定义的acl
                'durationSeconds' => 43200, //STS凭证有效时间
            );
        $response = $client->getSessionToken($request);
        $accessKeyID= $response->accessKeyId;
        $secretAccessKey= $response->secretAccessKey;
        $sessionToken = $response->sessionToken;
        $BOS_TEST_CONFIG = array(
            'credentials' => array(
                'accessKeyId' => $accessKeyID,
                'secretAccessKey' => $secretAccessKey,
                'sessionToken' => $sessionToken
            ),
            'endpoint' => 'bj.bcebos.com',
            'protocol' => 'http',
        );
        return $BOS_TEST_CONFIG;
    }

然后调用参数生成bucket对象

 public function __construct(){

        header("Content-type:text/html;charset=utf-8");
        global $BOS_TEST_CONFIG;
        $BOS_TEST_CONFIG = $this->sampleConf();
        parent::__construct();
        $this->Client = new BosClient($BOS_TEST_CONFIG);

        if(!$this->Client->doesBucketExist($this->bucket)){
            exit('bucket不存在或已删除');
        }
    }

生成对象之后就自己写了一个上传文件的方法用ajax调用

<script type="text/javascript">
    var data = new FormData();
    //var j = 0;
    $('#file').change(function(){

        $.ajax({
            url:'/home/index/upload',
            type:'post',
            dataType:'json',
            data:data,
            cache: false,
            contentType: false,
            processData: false,
            beforeSend:function(){
                $.each($('#file')[0].files, function(i,file) {
                    data.append('upload_file', file);
                    //j = j + 1;
                });
            },
            success:function(data){
                if(data.status == 1){
                    alert(data.msg);
                }else{
                    alert('上传出错');
                }
            },
            error:function(){
                alert('上传出错');
            },
        });

    });
</script>

上传文件到PHP服务器端后执行$info = $this->Client->putObjectFromFile($this->bucket,$key.'.'.$suffix[1],$filepath.$filename);这个方法就能上传到自己设置的bucket对象里面。 上传之后发现自己在BOS里面取不到数据的,然后后面才看到还有一个文档服务DOC这么一个东西 然后才发现自己一直弄错了,上传文档的时候还要参照文档服务api给出来的顺序先注册文档,然后上传发布文档,生成文档的documentId才能在DOC里面拿到数据,开始的时候就是接口的签名的问题https://cloud.baidu.com/doc/Reference/AuthenticationMechanism.html#.51.FB.C9.2A.A8.9E.A9.B9.87.29.3A.F8.B2.42.64.25 这个文档写的我反正是看的迷迷糊糊的,可能是自己的理解能力有点问题吧,后面弄了一个签名,可以了。

/*
     * generateAuthorization 签名
     * param $ak ak
     * param $sk sk
     * param $method 方法/POST GET HEAD PUT DELETE
     * param $host 服务器
     * param $uri
     * param $params
     * param $timestamp
     * param $expirationInSeconds
     * */
    public function generateAuthorization($ak, $sk, $method, $host, $uri, $params, $timestamp, $expirationInSeconds) {
        $timeStr = $timestamp->format("Y-m-d\TH:i:s\Z");
        $authStringPrefix = "bce-auth-v1/{$ak}/{$timeStr}/{$expirationInSeconds}";
        $signingKey = hash_hmac('SHA256', $authStringPrefix, $sk);
        $canonicalHeader1 = "host;x-bce-date";
        $canonicalHeader2 = "host:{$host}\n" . "x-bce-date:" . urlencode($timeStr);
        $httpUtil = new HttpUtil();

        $canonicalUri = $httpUtil->getCanonicalURIPath($uri);
        $method = strtoupper($method);

        $canonicalString = $httpUtil->getCanonicalQueryString($params);
        $canonicalRequest = "{$method}\n{$canonicalUri}\n{$canonicalString}\n{$canonicalHeader2}";

        $signature = hash_hmac('SHA256', $canonicalRequest, $signingKey);
        $authorization = "bce-auth-v1/{$ak}/{$timeStr}/{$expirationInSeconds}/{$canonicalHeader1}/{$signature}";
        return $authorization;
    }

签名通过之后肯定是在上传方法里面通过注册上传和发布三个步骤了

/*
     *upload 上传方法 上传到bucket DOC
     * */
    public function upload(){
        if ($_FILES["upload_file"]["error"] > 0) {
            echo json_encode(array('status'=>0,'msg'=> $_FILES["upload_file"]["error"]));
            exit;
        }
        $route = getcwd();
        $filepath = $route.'/Attachment/'.date('Y').'/'.date('m').'/';
        $suffix = explode('.',$_FILES["upload_file"]["name"]);
        $filename =  substr(md5($suffix[0].uniqid()),0,16).'.'.$suffix[1];
        if (!file_exists($filepath)){
            mkdir ($filepath,0777,true);
        }
        move_uploaded_file($_FILES["upload_file"]["tmp_name"],$filepath.$filename);
        $key = 'Object'.$this->__randStr();
        $info = $this->Client->putObjectFromFile($this->bucket,$key.'.'.$suffix[1],$filepath.$filename);
        $register = $this->register($key,$suffix[1]);//注册文件
        if($register){
            $source = $this->source($key,$suffix[1]);//上传到DOC
            $source = json_decode($source);
            $this->publish($source->documentId);//发布
            if($info){
                echo json_encode(array('status'=>1,'msg'=> '上传成功'));
            }else{
                echo json_encode(array('status'=>0,'msg'=> '上传失败'));
            }
        }else{
            echo json_encode(array('status'=>0,'msg'=> '上传失败'));
        }
    }
/*
     * register 注册DOC方法
     * param $key 文件名
     * param $format 文件格式
     * */
    public function register($key,$format){
        $uri = "/v2/document";
        $params = array("register" => "");
        $body = array(
            "title" => $key,
            "format" => $format,
            //"bucket" => $this->bucket,
            //"object" => 'Objecty3rlNBYS6ZNEgVjr.docx',
        );
        $data = $this->curl($uri,$params,"POST",60,$body,'register');
        //print_r($data);
        return $data;
    }
    /*
     * source 上传DOC方法
     * param $key 文件名
     * param $format 文件格式
     * */
    public function source($key,$format){
        $uri = "/v2/document";
        $params = array("source" => "bos");
        $body = array(
            "title" => $key,
            "format" => $format,
            "bucket" => $this->bucket,
            "object" => $key.'.'.$format,
        );
        $data = $this->curl($uri,$params,"POST",60,$body,'source=bos');
        //print_r($data);
        return $data;
    }
    /*
     * publish 方法,发布文档
     * param $documentId 文档docid
     * */
    public function publish($documentId){
        $uri = '/v2/document/'.$documentId;
        $params = array("publish" => "");
        $body = array("documentId"=>$documentId);
        $data = $this->curl($uri,$params,"PUT",60,$body,'publish');
        //print_r($data);
        return $data;
    }
/*
     * curl 接口访问通用方法
     * param $uri 接口
     * param $params 参数
     * param $method $method 访问方法
     * param $expirationInSeconds 时间/s
     * param $body body 参数
     * param $x 接口参数
     * */
    public function curl($uri,$params,$method,$expirationInSeconds,$body,$x){
        // 第一步:生成认证字符串
        date_default_timezone_set('UTC');
        $timestamp = new \DateTime();
        $sign = $this->generateAuthorization($this->ak,$this->sk,$method,$this->host,$uri,$params,$timestamp,$expirationInSeconds);
        $timeStr = $timestamp->format("Y-m-d\TH:i:s\Z");
        $url = "http://{$this->host}{$uri}?{$x}";
        $timeStr = $timestamp->format("Y-m-d\TH:i:s\Z");
        $head =  array(
            "Content-Type: application/json",
            "Authorization:{$sign}",
            "x-bce-date:{$timeStr}",
        );
        $bodyStr = json_encode($body);
        $curlp = curl_init();
        curl_setopt($curlp, CURLOPT_URL, $url);
        curl_setopt($curlp, CURLOPT_HTTPHEADER, $head);
        curl_setopt($curlp, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($curlp, CURLOPT_POSTFIELDS, $bodyStr);
        curl_setopt($curlp, CURLINFO_HEADER_OUT, 1);
        curl_setopt($curlp, CURLOPT_RETURNTRANSFER, 1);
        $response = curl_exec($curlp);
        curl_close($curlp);
        return $response;
    }

这样就整个文档上传的主要步骤了,渲染到web页面还是很快的, http://static.bcedocument.com/reader/v2/console/index.html?docId=doc-gkjraanw4f89uu5&token=TOKEN&host=BCEDOC&enviroment=online 直接把这个页面copy下来就很省事了。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部