conohaのオブジェクトストレージをphpで利用する

conohaのオブジェクトストレージをphp経由で利用したのでその備忘録を残していきます。

基本の流れは
認証トークン取得 ⇒ 認証トークンを利用してREST APIをたたく ⇒ 必要に応じて戻り値を利用する

以下ソースコードの一部を抜粋します、実際のソースコードとは差異があります。(動作未確認)

ConohaAPI

   
class  ConohaAPI {
    //ユーザー名
    const userName = "gncu*****";
    //パスワード
    const pass = "*****";
    //テナント名
    const tenantName = "gnct*****";
    //テナントID
    const tenantId = "*****";
    //認証用URL
    const authUrl = "https://identity.tyo1.conoha.io/v2.0/";
    //オブジェクトストレージエンドポイントURL
    const endpointUrl = "https://object-storage.tyo1.conoha.io/v1/nc_".self::tenantId."/";

    //認証トークン
    private $token = "";

   //認証トークンの取得
    public function getToken(){
        if($this->token != ""){
            return $this->token;
        }
        $curl = curl_init();
        // HTTPヘッダー
        $headers = array(
         'Content-Type: application/json'
        );
        //認証用情報の設定
        $data = array(
            'auth' => array(
                'tenantName' => self::tenantName,
                'passwordCredentials' => array(
                'username' => self::userName,
                'password' => self::pass
                )
            )
        );
        $postdata = json_encode($data);

        // URL
       $url = self::authUrl . '/tokens';
        // cURLオプション
        $options = array(
            // HTTPヘッダーの設定
            CURLOPT_HTTPHEADER => $headers,
            // URL
            CURLOPT_URL => $url,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $postdata,
            CURLOPT_RETURNTRANSFER => true,
        );
        curl_setopt_array($curl, $options);
        // HTTPリクエストを実行
        $body = curl_exec($curl);
        
        if(curl_errno($curl)) {
            $msg = sprintf('cURL error: %s', curl_error($curl));
            throw new RuntimeException($msg);
        }
        // HTTPステータスコードを取得します。
        // 200:成功、401:失敗
        $status_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);

        if(curl_errno($curl) OR $status_code != 200) {
            $msg = sprintf(
                'Authentication failed. The auth server returned status code(%d).',
                $status_code
            );
            throw new RuntimeException($msg);
        }
        // 戻り値のjson文字列をデコードする
        $authinfo = json_decode($body);
        // 認証トークン取得
        $this->token = $authinfo->access->token->id;
        return $this->token;
     }
    /**
     * 認証トークンを利用したリクエストを行います
     * @param type $url
     * @param type $type
     * @param type $optionAr
     * @param string $headers
     * @return type
     * @throws RuntimeException
     */
    private function request($url, $type = "GET",$optionAr = array(),$headerAr = array()){
        // cURLの初期化
        $curl = curl_init();
        // HTTPヘッダーが指定されていればそちらを優先する
        $headers = array(
            "X-Auth-Token"=>'X-Auth-Token: ' . $this->getToken(),
            "Accept"=>'Accept: application/json'
        );
        if($headerAr && is_array($headerAr)){
            //キーが重複する場合後のものが優先される
            $headers = $headers + $headerAr;
        }  
        
        // cURLのオプション
        $options = array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => $headers,
        );
        if($type == "PUT"){
            $options[CURLOPT_PUT] = true;
//            $options[CURLOPT_CUSTOMREQUEST] = $type;
        }else{
            $options[CURLOPT_CUSTOMREQUEST] = $type;
        }

        
        //その他オプション指定があればマージする
        if($optionAr && is_array($optionAr)){
            //キーが重複する場合後のものが優先される
            $options = $options + $optionAr;
        }
        curl_setopt_array($curl, $options);
        // HTTPリクエストを実行
        // レスポンスには何も含まれていません。
        $body = curl_exec($curl);
        if(curl_errno($curl)) {
            $msg = sprintf('cURL error: %s', curl_error($curl));
            throw new RuntimeException($msg);
        }
        // HTTPステータスコードを取得します。
        $status_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        $array = array(
           "body"=> $body,
           "status_code"=> $status_code,
        );
        return $array;
    }

    /**
     * コンテナを作成する 作成済みの場合return true, 失敗した場合はExceptionを投げる
     * @param type $contenarName
     * @return boolean
     */
    function createContenar($contenarName){
        $url = self::endpointUrl.$contenarName;
        
        $result = $this->request($url,"PUT");
        if($result["status_code"] == 200 || $result["status_code"] == 201){
            return true;
        }
    }

    /**
     * オブジェクトのアップロードを行います。実行前にcreateContenarを実行してください
     * @param type $contenarName
     * @param type $fileName  //保存名
     * @param type $path    //データ
     * @return boolean
     */
    function uploadObject($contenarName = "", $fileName = "", $path = ""){

        if($contenarName == "" || $fileName == "" || $path == ""){
            return false;
        }
        
        //拡張子を決める
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $mime = finfo_file($finfo, $path);
        // Content-Typeヘッダーでアップロードするオブジェクトの形式を指定します。
        //目的に応じて随時修正してください。
        $contentType = "";
        if (preg_match('/jpeg$/', $mime)) {
                $contentType = "Content-Type: image/jpg;";
        } else if (preg_match('/gif$/', $mime)) {
                $contentType = "Content-Type: image/gif;";
        } else if (preg_match('/png$/', $mime)) {
                $contentType = "Content-Type: image/png";
        } 
        if ($contentType == "") {
                return false;
        }       
        
        $headerAr = array(
            "Content-Type"=>$contentType,

        );
        $opsionAr = array(
            CURLOPT_INFILE => fopen($path,"r"),
        );
        
        
        $url = self::endpointUrl.$contenarName."/".$fileName;
        $result = $this->request($url,"PUT", $opsionAr, $headerAr);
        // 201成功
        if($result["status_code"] === 201){
            return true;
        }
        return false; 
    }
    /**
     * コンテナ情報の取得、$pathを指定すると "$contenarName/$path/"配下を取得します
     * @param type $contenarName
     * @param type $path 取得するパス
     */
    function getContenarInfo($contenarName = "",$path = ""){
        $url = self::endpointUrl.$contenarName;
        if($path){
            $url = $url."?path={$path}";
        }
         
        $result = $this->request($url);
        print_r($result)
    }
    /**
     * オブジェクト情報の表示
     * @param type $contenarName
     * @param type $objName
     */
    function getObjectInfo($contenarName = "",$objName= "") {
        $url = self::endpointUrl.$contenarName."/".$objName;
        $result = $this->request($url);
        
        print_r($result);
    }

}

開発中のいろいろ

CURLOPT_PUTとCURLOPT_CUSTOMREQUESTの違い

アップロードの際はPUTを利用するのですがCURLOPT_CUSTOMREQUEST=PUTではファイルがうまくアップできずに悩みましたが、CURLOPT_PUTにすることで解決しました。
https://stackoverflow.com/questions/44918152/curlopt-put-vs-curlopt-postfields
CURLOPT_PUTとCURLOPT_CUSTOMREQUEST=PUTで動作が微妙に違うのですね。。

オブジェクトの名前と取得

ディレクトリを作って階層で管理したい場合はオブジェクト名に”dirName/filename”のようにすれば指定すればディレクトリが作成されるようです。

取得する場合はオブジェクト名に”dirName/filename”を指定する。階層ごとに取得したい場合はコンテナ取得のリクエストの際に”?path=dirName”のようにGETパラメータを追加すればできました。
上記コードを利用すると

//dirName/filename取得
$ConohaAPI->getObjectInfo("コンテナ名","dirName/filename")

//dirName配下のオブジェクト取得
$ConohaAPI->getContenarInfo("コンテナ名","dirName")

という形式になります。

正規表現は使えないのだろうか。。
リファレンスを見てもパラメータのみで説明がないため手探りで調べているんですがまだわかっていません。
それらしいパラメータもあるんですがうまくいかず用途が違うのか使い方が違うのか、そもそも使用できないのかはっきりしません。
ご存知の方教えてください。

とりあえず現状は正規表現なしでも大丈夫なので気が向いたら調べようと思います。

カテゴリー: php, server タグ: ,

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*