PHPでDropboxのファイル取得

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

(2022年2月12日)PHP8対応,リファラ・チェック改良

目次

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

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 必須 検索対象ディレクトリ。Dropboxのパスで指定する。
query 必須 検索パターン。ワイルドカードに加え、正規表現を利用できる。
start 任意 検索開始番号。省略時は0。
max_results 任意 検索でヒットした情報の最大数。省略時は100。
mode 任意 検索対象
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: }

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

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

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

入力パラメータ
フィールド名 要否 内  容
path 必須 ダウンロードするファイルのフルパス名。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のファイル取得

0119: /**
0120:  * Dropboxのファイル取得
0121:  * @param   string $query  検索パターン
0122:  * @return  array(取得データ,WebAPI,エラーメッセージ)
0123: */
0124: function getDropboxTextFile($query) {
0125:     $res = $api = $errmsg = '';
0126:     $pdb = new pahooDropboxAPI();    //Dropbox APIクラス
0127: 
0128:     if ($pdb->iserror()) {
0129:         $errmsg = $pdb->geterror();
0130:     //ファイル検索
0131:     } else if (($files = $pdb->glob($query)) == FALSE) {
0132:         $errmsg = $query . ' : not found';
0133:     //通常ファイルかどうか
0134:     } else if (! $pdb->is_file($files[0])) {
0135:         $errmsg = $files[0] . ' : is not a file';
0136:     //ファイル内容取得
0137:     } else if (($res = $pdb->file_get_contents($files[0])) == FALSE) {
0138:         $errmsg = $files[0] . ' : ' . $pdb->geterror();
0139:     }
0140:     $api = $pdb->webapi;
0141:     $pdb = NULL;
0142: 
0143:     return array($res$errmsg$api);
0144: }

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

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

参考サイト

(この項おわり)
header