PHPで Dropboxのファイル取得

(1/1)
PHP を使い、Dropbox で共有しているファイルを取得するプログラムを作る。
2018 年(平成 30 年)9 月現在、Dropbox API v2 では PHP用の SDK が用意されていないため、ここでは PHP 5 以上でフレームワークを必要とせず、PHP のファイル操作関数に似せたメソッドを用意することを目標にする。

目次

サンプル・プログラムの実行例

PHPで Dropboxのファイル取得

サンプル・プログラムのダウンロード

圧縮ファイルの内容
getDropBox.phpサンプル・プログラム本体。
pahooDropboxAPI.phpDropbox APIクラス pahooDropboxAPI。
Dropbox APIクラスの使い方は「PHPで Dropboxのファイル取得」を参照。include_pathが通ったディレクトリに配置のこと。

Dropbox API 利用の準備

Dropbox API 利用の準備
Dropbox API v2 にアクセスし、左図の画面の Create apps をクリックし、必要な情報を入力する。
Dropbox API 利用の準備
API は "Dropbox API" を選択し、アクセスできるフォルダが必要に応じて、いずれか一方を選択する。

つづいて Dropbox API Explorer にアクセスし、左ペインからどれか API を選ぶと、下図の画面になる。
Dropbox API 利用の準備
Get Token をクリックすると、アクセス・トークンが画面に表示される。
PHP プログラムでは、このアクセス・トークンを使って API にアクセスする。

解説:pahooDropboxAPI クラス

Dropbox API を使うメソッドは、PHP のクラスを使って定義している。
クラスについては「PHP でクラスを使ってテキストの読みやすさを調べる」で解説している。
クラスファイル "pahooDropboxAPI" は、組み込み関数  require_once  を使って読めるディレクトリに配置する。ディレクトリは、設定ファイル php.ini に記述されているオプション設定 include_path に設定しておく。

0021:     //Dropbox API Access Token:各自で設定
0022:     //https://www.dropbox.com/lp/developers
0023:     var $DROPBOX_TOKEN   = '**************************';

先ほど取得したアクセス・トークンは、クラス変数 $DROPBOX_TOKEN に代入しておく。

解説:Dropbox API リクエスト

Dropbox API へのリクエストは、メソッド requestDropboxAPIv2 で処理する。パラメータは POST で指定された URL に投げる。
リクエストは全て https通信で処理されることから、「PHP セキュリティ対策:SSL通信を行う」で紹介した cURL 関数群を用いる。

0077: /**
0078:  * Dropbox API v2:アクセストークンを用いたリクエスト
0079:  * @param string $url    リクエストURL
0080:  * @param array  $argv   Dropbox-API-Argに渡すパラメータ配列(省略可能)
0081:  * @param array  $post   POSTに渡すパラメータ配列(省略可能)
0082:  * @param string $upload アップロードするデータ
0083:  * @return bool TRUE:リクエスト成功/FALSE:失敗
0084: */
0085: function requestDropboxAPIv2($url$argv=NULL$post=NULL$upload=NULL) {
0086:     $flagArg = FALSE;
0087:     $headers[] = 'Authorization: Bearer ' . $this->DROPBOX_TOKEN;
0088: 
0089:     // cURLを使ってリクエスト
0090:     $curl = curl_init() ;
0091:     curl_setopt($curlCURLOPT_URL , $url);
0092:     curl_setopt($curlCURLOPT_HEADER, 1) ; 
0093:     curl_setopt($curlCURLOPT_SSL_VERIFYPEER , FALSE);  //証明書は無視
0094:     curl_setopt($curlCURLOPT_RETURNTRANSFER,  TRUE);       //結果を文字列で
0095:     curl_setopt($curlCURLOPT_CUSTOMREQUEST, 'POST');
0096:     curl_setopt($curlCURLOPT_TIMEOUT, 5);
0097:     if ($argv != NULL) {
0098:         $headers[] = 'Dropbox-API-Arg: ' . json_encode($argv);
0099:         $flagArg = TRUE;
0100:     }
0101:     if ($upload != NULL) {
0102:         $headers[] = 'Content-Type: application/octet-stream';
0103:         curl_setopt($curlCURLOPT_POSTFIELDS$upload);
0104:         $flagArg = FALSE;
0105:     } else if ($post != NULL) {
0106:         $headers[] = 'Content-Type: application/json';
0107:         curl_setopt($curlCURLOPT_POSTFIELDSjson_encode($post));
0108:     }
0109:     curl_setopt($curlCURLOPT_HTTPHEADER$headers);
0110: 
0111:     $res1 = curl_exec($curl);
0112:     $res2 = curl_getinfo($curl);
0113:     curl_close($curl);
0114:     $res = substr($res1$res2['header_size']);
0115: 
0116:     //結果処理
0117:     $this->webapi = $url;
0118:     preg_match("/HTTP\/[0-9\.]+\s([0-9]+)\s(.+)/ims", $res1$arr);
0119:     if (! isset($arr[2])) {
0120:         $this->error   = TRUE;
0121:         $this->errmsg  = 'Dropbox API failure';
0122:     } else if ($arr[1] >= 300) {
0123:         $json = json_decode($res);
0124:         $this->error   = TRUE;
0125:         $this->errmsg  = $arr[2];
0126:     } else {
0127:         $this->responses = $flagArg ? $res : json_decode($res);
0128:     }
0129:     return (! $this->error);
0130: }

Dropbox API v2:ファイル検索

リクエストURL
https://api.dropboxapi.com/2/files/search

入力パラメータ
項目名 フィールド名 内  容
検索パス path string 【必須】検索対象ディレクトリ。Dropboxのパスで指定する。
検索パターン query string 【必須】検索パターン。ワイルドカードに加え、正規表現を利用できる。
開始番号 start integer 検索開始番号。省略時は0。
最大結果数 max_results integer 検索でヒットした情報の最大数。省略時は100。
検索対象 mode string filename:ファイル名とフォルダ名
filename_and_content:ファイル名、フォルダ名、及びファイルの内容
deleted_filename:削除したファイル目とフォルダ名
省略時はfilename。
応答データ構造(http) json matches match_type tag filename/content/both metadata .tag ファイル/フォルダの種別 name ファイル名 id ファイルID client_modified クライアント更新日時 server_modified サーバ更新日時 rev ファイルRev size ファイルサイズ(バイト) path_lower フルパス名(小文字) path_display フルパス名 sharing_info 共有情報 matches 結果#2 matches 結果#3 more true/false start 開始番号

0132: /**
0133:  * Dropbox API v2:パターンにマッチするファイルを探す
0134:  * @param string $pattern パターン
0135:  * @return array マッチするファイル・ディレクトリを含む配列/FALSE:存在しない
0136: */
0137: function glob($pattern) {
0138:     $url = 'https://api.dropboxapi.com/2/files/search'; //リクエストURL
0139:     $arr = pathinfo($pattern);
0140:     $post['path']  = $arr['dirname'];
0141:     $post['query'] = $arr['basename'];
0142: 
0143:     $res = array();
0144: 
0145:     if ($this->requestDropboxAPIv2($urlNULL$post) == FALSE) {
0146:         $res = FALSE;
0147:     } else if (isset($this->responses->matches[0]->metadata->name)) {
0148:         foreach ($this->responses->matches as $mat) {
0149:             $res[] = $mat->metadata->path_display;
0150:         }
0151:     } else {
0152:         $res = FALSE;
0153:     }
0154: 
0155:     return $res;
0156: }

ファイル検索は、組み込み関数  glob  に似せたメソッド glob を用意した。

Dropbox API v2:通常ファイルかどうか

メソッド [#glob:glob] でヒットした内容が、通常ファイルかどうか(フォルダではないかどうか)を検査するために、ファイル検索API の応答にあるタグ情報をチェックする。

0158: /**
0159:  * Dropbox API v2:ファイルのタグ情報を取得する
0160:  * @param string $filename ファイル名(パスを含む)
0161:  * @return string タグ情報
0162: */
0163: function get_tag($filename) {
0164:     $url = 'https://api.dropboxapi.com/2/files/search'; //リクエストURL
0165:     $arr = pathinfo($filename);
0166:     $post['path']  = $arr['dirname'];
0167:     $post['query'] = $arr['basename'];
0168: 
0169:     if ($this->requestDropboxAPIv2($urlNULL$post) == FALSE) {
0170:         $res = FALSE;
0171:     } else if (isset($this->responses->matches[0]->metadata->name)) {
0172:         $tag = '.tag';
0173:         $res = $this->responses->matches[0]->metadata->$tag;
0174:     } else {
0175:         $res = FALSE;
0176:     }
0177:     return $res;
0178: }
0179: 
0180: /**
0181:  * Dropbox API v2:ファイルまたはディレクトリが存在するかどうか調べる
0182:  * @param string $filename ファイル名またはフォルダ名(パスを含む)
0183:  * @return bool TRUE:存在する/FALSE:存在しない
0184: */
0185: function file_exists($filename) {
0186:     return $this->get_tag($filename) == FALSE ? FALSE : TRUE;
0187: }
0188: 
0189: /**
0190:  * Dropbox API v2:通常ファイルかどうかを調べる
0191:  * @param string $filename ファイル名(パスを含む)
0192:  * @return bool TRUE:存在する/FALSE:存在しない
0193: */
0194: function is_file($filename) {
0195:     return $this->get_tag($filename) == 'file' ? TRUE : FALSE;
0196: }
0197: 
0198: /**
0199:  * Dropbox API v2:ディレクトリかどうかを調べる
0200:  * @param string $filename ファイル名(パスを含む)
0201:  * @return bool TRUE:存在する/FALSE:存在しない
0202: */
0203: function is_dir($filename) {
0204:     return $this->get_tag($filename) == 'folder' ? TRUE : FALSE;
0205: }

通常ファイルかどうかを検査するには、組み込み関数  is_file  に似せたメソッド is_file を用意した。

Dropbox API v2:ファイルの内容取得

リクエストURL
https://content.dropboxapi.com/2/files/download

入力パラメータ
項目名 フィールド名 内  容
ファイル名 path string 【必須】ダウンロードするファイルのフルパス名。Dropboxのパスで指定する。
ファイルIDやrevでも指定できる。
応答データ構造(http) json .tag ファイル/フォルダの種別 name ファイル名 id ファイルID client_modified クライアント更新日時 server_modified サーバ更新日時 rev ファイルRev size ファイルサイズ(バイト) path_lower フルパス名(小文字) path_display フルパス名 sharing_info 共有情報 property_groups プロパティ・グループ has_explicit_shared_members true/false content_hash ハッシュ値 data ダウンロード・データ本体

0207: /**
0208:  * Dropbox API v2:ファイルの内容取得
0209:  * @param string $filename ファイル名(パスを含む)
0210:  * @return string ファイル内容/FALSE:失敗
0211: */
0212: function file_get_contents($filename) {
0213:     $url = 'https://content.dropboxapi.com/2/files/download'; //リクエストURL
0214:     $argv['path']  = $filename;
0215: 
0216:     return ($this->requestDropboxAPIv2($url$argv) == FALSE) ?
0217:                 FALSE : $this->responses;
0218: }

ファイルの内容取得は、組み込み関数  file_get_contents  に似せたメソッド file_get_contents を用意した。

サンプル・プログラムの流れ

PHPで Dropboxのファイル取得

0087: /**
0088:  * Dropboxのファイル取得
0089:  * @param string $query  検索パターン
0090:  * @return array(取得データ,WebAPI,エラーメッセージ)
0091: */
0092: function getDropboxTextFile($query) {
0093:     $res = $api = $errmsg = '';
0094:     $pdb = new pahooDropboxAPI();    //Dropbox APIクラス
0095: 
0096:     if ($pdb->iserror()) {
0097:         $errmsg = $pdb->geterror();
0098:     //ファイル検索
0099:     } else if (($files = $pdb->glob($query)) == FALSE) {
0100:         $errmsg = $query . ' : not found';
0101:     //通常ファイルかどうか
0102:     } else if (! $pdb->is_file($files[0])) {
0103:         $errmsg = $files[0] . ' : is not a file';
0104:     //ファイル内容取得
0105:     } else if (($res = $pdb->file_get_contents($files[0])) == FALSE) {
0106:         $errmsg = $files[0] . ' : ' . $pdb->geterror();
0107:     }
0108:     $api = $pdb->webapi;
0109:     $pdb = NULL;
0110: 
0111:     return array($res$errmsg$api);
0112: }

サンプル・プログラム "getDropBox.php" は、パターン "/memo/*.txt" でファイル検索を行い、最初にヒットしたテキスト・ファイルを画面に表示するというものである。
主な処理はユーザー関数 getDropboxTextFile の通りである。検索パターンは、各自の環境に合わせて変更してほしい。

また、クラス pahooDropboxAPI には、ファイルにデータを書き込んだりアップロードするメソッド、ファイルを削除するメソッドも用意してある。各自の責任において活用してほしい。

参考サイト

(この項おわり)
header