PHPのcURL+DropboxのAPI/SDKで連携する方法
Dropboxを有効活用していますか?DropboxのAPIを通して現在稼働しているシステムと連携することができれば大量のデータを保存できるDropboxをより効率的に活用することができます。そのためには、まずDropboxのAPIの使い方を理解する必要があります。本文書では、PHPのcURLを使ってDropboxに保存されているファイルを操作を通して、Dropbox APIの使い方と理解を深めていきます。もしこれまでに外部サービスとの連携の経験がない人であればDropboxとの連携ができるようになるとGUIを介さずにDropboxの操作を行うことができるのでエンジニア/プログラマーとして一つステップアップした気持ちになれるはずです。
本文書では、cURLをある程度理解している方を対象に記載しています。cURLについて理解が不足している方は、まず下記の記事に目を通してみてください。
本文書を読み終えるとDropboxのAPIを通して下記の操作が行えるようになります。
- 指定したフォルダ下にあるファイル/フォルダ一覧を表示
- 指定したフォルダへの任意のファイルのアップロード
- 保存されているファイルのダウンロード
- 保存されているファイルのリンクの取得
- 保存されているフォルダ/ファイルの存在の取得
- 新規フォルダの作成
目次
アプリケーションの作成
PHPのcURL環境で、Dropboxのファイル操作を行うためには、アプリケーションの作成(Create an App)を行う必要があります。アプリケーションを作成することでDropboxに接続するために必要な認証情報であるアクセストークンの取得を行います。アプリケーションを作成する目的は、アクセストークンを取得することにあります。
アプリケーションの作成は、Dropboxの開発者サイトで行います。以下のリンクからDropboxの開発者サイトに移動してください。
URL:https://www.dropbox.com/developers
下記がDropboxの開発者サイトのトップページです。”アプリの作成”ボタンをクリックします。
ログイン画面または登録画面が表示されるのでGoogleアカウント、Appleのアカウント、メールアドレスのいずれかの方法でログインを行ってください。
ログインを行うとアプリの作成画面が表示されます。
アクセスできる範囲の選択ができますが、すべてのファイルとフォルダにアクセスできるFull Dropboxを選択します。
アプリケーションについては、任意の名前のアプリケーション名(3. Name your app)を入れてください。入力して”Terms and Conditions”にチェックを入れると”Create app”ボタンがクリック可能になります。
アプリケーションの作成が完了すると下記の画面が表示されます。
ここでは、アクセストークンを取得する必要があるので、OAuth2のGenerated access tokenの下にあるGenerateボタンをクリックしてください。クリックするとアクセストークンの文字列が表示されます。これが今後必要になるアクセス情報です。それ以外については、入力しなくてもこれから説明を行うcURLでのファイル操作には影響はありません。
Dropbox内フォルダのファイル一覧を取得
APIを利用するためには、Dropbox側で用意している各操作用のURL、送信するヘッダーの内容、パラメータを事前に確認しておく必要があります。確認するためには、DevelopersページのDocumentationの下にあるAPI ReferenceのHTTP Referenceをクリックします。
User EndpointsではDropbox API v2で利用できるAPIのエンドポイントが表示されます。
右のコラムからDropboxに保存されているファイルのリスト表示を行う/list_foldersを探して、クリックします。
ファイルのリストを表示したい場合にアクセスするURLの情報(エンドポイント)や、アクセスする際に必要となるパラメータの情報が記載されています。この内容を元にcurlの設定を行います。
ドキュメントにはpath以外のパラメータも記載されています。そのほかのパラメータ(recursive,include_media_info等)は初期値が決まっているので、今回は省略しています。他のパラメータを設定したい場合は、$post_fields変数の配列にパラメータを追加してください。
Dropboxのドキュメントを元に設定したPHPのプログラムは下記の通りになります。ファイルは任意の名前をつけることができるのでここではindex.phpとしています。
<?php
$url = "https://api.dropboxapi.com/2/files/list_folder";
$headers = [
'Authorization: Bearer XXXXXX', //(1)取得したアクセストークン
'Content-Type: application/json'
];
$post_fields = [
"path" => "/test/" //(2)ファイル一覧を取得したいフォルダのパス
];
$options = [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($post_fields)
];
$ch = curl_init();
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
curl_close($ch);
var_dump($result);
“(1)取得したアクセストークン”は、アプリケーションの作成時に取得したアクセストークンを入力してください。”(2)ファイル一覧を取得したいフォルダのパス”は、各自の環境に依存するので、ファイル一覧を取得したいDropbox上のフォルダのパスを記述してください。”/”をpathに設定した場合はエラーとなるので必ずDropbox上にフォルダを作成してその中にファイルを保存してください。
動作確認のためPHPの開発サーバを利用します。下記のコマンドを作成したPHPファイルが保存されているフォルダで実行します。
% php -S localhost:8000
PHPの開発サーバがポート番号8000で起動するのでブラウザからlocalhost:8000にアクセスすると実行されます。
ブラウザ上に”Error in call to API function “files/list_folder”: Your app is not permitted to access this endpoint because it does not have the required scope ‘files.metadata.read’. The owner of the app can enable the scope for the app using the Permissions tab on the App Console.”のメッセージが表示された場合はScopeによるアクセス制限が適切に行われていないため設定を行う必要があります。
作成したアプリの画面から”Permissions”のタブを設定するとScopeを設定することができます。デフォルトではaccount_info.readのみチェックが入っている状態です。files/list_folderを利用するためにはfiles.metadata.readをチェックする必要があります。本番で利用する場合には適切なScopeを設定する必要がありますがここではfiles_metadata.writeをチェックします。files_metadata.writeをチェックするとfiles_metadata.readにもチェックが入ります。ファイルのダウンロードなどにはfile.contente.readやwriteも必要になるのでチェックを行ってください。チェック後は画面下に表示されている”Submit”ボタンをクリックしてください。Scopeを変更した場合は再度アクセストークンの再作成が必要なので忘れずに行ってください。
Scopeが適切に設定されていれば下記のような文字列が表示さます。表示された場合はAPI経由でのDropboxへのアクセスは成功しています。
string(1498)
"{"entries":
[{".tag": "file",
"name": "dropbox\u306eAPI.docx",
"path_lower": "/test/dropbox\u306eapi.docx",
"path_display":"/test/dropbox\u306eAPI.docx",
"id": "id:2ozr6e1JbiAAAAAAAAAApA",
"client_modified": "2018-11-06T11:22:21Z",
json_decodeを使用してデコードを行うと日本語の文字に変換されるので、実際のファイル名と一致するのか確認することができます。
var_dump(json_decode($result));
testフォルダの下にdropboxのapi.docxというワードファイルがあることを確認できます。ファイル名以外にも修正日時、サイズ等も含まれています。サーバから送られてきた値については、ドキュメントを見ながら確認してください。
object(stdClass)#3067 (3)
{ ["entries"]=> array(3)
{ [0]=> object(stdClass)#3064 (10)
{ [".tag"]=> string(4) "file"
["name"]=> string(18) "dropboxのAPI.docx"
["path_lower"]=> string(24) "/test/dropboxのapi.docx"
["path_display"]=> string(24)
下記では、サーバから送られてきた情報の中でファイル名だけforeachを使用して取り出し、表示させていきます。
$result = json_decode($result);
foreach($result->entries as $entry){
echo '<p>'.$entry->name.'<p>';
}
testフォルダには、3つのファイルを保存していたので、ブラウザには保存されてる3つのファイル名が表示されます。
開発サーバを利用して動作確認を行いましたがphpコマンドでも実行することができます。
% php index.php
DropBoxにファイルをアップロード
次は、DropboxのAPIを利用して、ファイルのアップロードを行います。Dropboxのドキュメントのuploadのページを開いてパラメータを確認してください。
Dropboxのドキュメントを元に設定したPHPのプログラムは下記の通りになります。
<?php
$url = "https://content.dropboxapi.com/2/files/upload";
$path = './XXX/XXX/アップロード手順.pdf';//(1)
$fp = fopen($path,'rb');
$filesize = filesize($path);
$headers = array(
'Authorization: Bearer XXXXXXXX', //(2)
'Dropbox-API-Arg: {"path":"/test/アップロード手順.pdf"}',//(3)
'Content-Type: application/octet-stream'
);
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => fread($fp, $filesize)
);
$ch = curl_init();
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
var_dump(json_decode($result));
(1)はアップロードを行いたいファイルのパスを設定してください。(2)では、アプリケーションの作成時に取得したアクセストークンを入力してください。(3)は、Dropbox側でファイルをアップロードするパスを設定してください。
プログラムを実行後、必ずDropbox側にファイルが作成されていることを確認し、サイズが0でないことも確認してください。プログラムの間違いやcrulの設定に誤りがあるとファイルは作成できているが、ファイルの中身がない(サイズ0)ということも起こりえます。
アップロード完了後、$result変数にサーバからの戻り値が入っているので、こちらでもサイズが0ではないか等確認することができます。戻り値についてはドキュメントを確認してください。
object(stdClass)#3067 (9)
{ ["name"]=> string(28) "アップロード手順.pdf"
["path_lower"]=> string(34)"/test/アップロード手順.pdf"
["path_display"]=> string(34) "/test/アップロード手順.pdf"
["id"]=> string(25) "id:2ozr6e1JbiAAAAAArQ"
["client_modified"]=> string(20)"2018-11-06T13:31:52Z"
["server_modified"]=> string(20) "2018-11-06T13:31:53Z"
["rev"]=> string(10) "c75d699c8f"
["size"]=> int(133026)
["content_hash"]=> string(64)
Dropboxからのファイルのダウンロード
次は、DropboxのAPIを利用して、ファイルのダウンロードを行います。DropboxのドキュメントのDownloadのページを開いてパラメータを確認してください。
ダウンロードのパラメータは、ダウンロードしたいDropbox上に保管されているファイルのパスを指定するのみなので、非常にシンプルです。指定方法はパス以外にもidなどがありますが直感的にわかりやすいパスを指定して行っています。
(1)では、アプリケーションの作成時に取得したアクセストークンを入力してください。(2)はダウンロードを行いたいファイルのパスを設定してください。$resultには、ダウンロードに指定したファイルのrawデータが入っているので、(3)には、本番環境ではサーバへの保存方法を記述してください。
<?php
$url = "https://content.dropboxapi.com/2/files/download";
$ch = curl_init();
$headers = array(
'Authorization: Bearer XXXXXXX', //(1)
'Content-Type: application/octet-stream',
'Dropbox-API-Arg: {"path":"/test/ダウンロード手順.pdf"}'//(2)
);
$options = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers,
);
curl_setopt_array($ch, $options);
$result= curl_exec($ch);
file_put_contents("ダウンロード手順.pdf", $result);//(3)
curl_close($ch);
Dropboxの中のファイルのリンク取得
次はDropboxのAPIのget_temporary_linkを利用してファイルのリンクのURLを取得します。リンク取得(URL)後はブラウザのアドレスバーにコピーすれば、Dropbox内に保存したファイルを手元のPCに直接ダウンロードすることができます。名前の通りtemporaryなのでリンクは4時間だけ有効なので注意が必要です。詳細はDropboxのドキュメントのget_temporary_linkのページを開いてパラメータを確認してください。
Dropboxのドキュメントを元に設定したPHPのプログラムは下記の通りになります。
$url = "https://api.dropboxapi.com/2/files/get_temporary_link";
$headers = array(
'Authorization: Bearer XXXXXXX', //(1)
'Content-Type: application/json'
);
$post = array(
"path" => "/test/ダウンロード手順.pdf"//(2)
);
$options = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($post),
);
$ch = curl_init();
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
var_dump(json_decode($result));
(1)では、アプリケーションの作成時に取得したアクセストークンを入力してください。(2)はリンクを取得したいファイルのパスを設定してください。
プログラム完了後、$result変数にサーバからの戻り値が入っているので、戻り値の中からリンクを取得する必要があります。その他の戻り値についてはドキュメントを確認してください。
object(stdClass)#3067 (2)
{ ["metadata"]=> object(stdClass)#3064 (9)
{ ["name"]=> string(28) "ダウンロード手順.pdf"
["path_lower"]=> string(34) "/test/ダウンロード手順.pdf"
["path_display"]=> string(34) "/test/ダウンロード手順.pdf"
["id"]=> string(25) "id:2ozr6e1JbiAAAAAAAAAArg"
下記のように記述するとブラウザの画面上にリンクの設定されたファイル名が表示されます。リンクをクリックするとダウンロードが開始されます。
$file_name = json_decode($result)->metadata->name;
$link = json_decode($result)->link;
echo '<a href="'.$link.'">'.$file_name.'</a>';
ブラウザには下記のようなリンクが表示されます。
Dropboxの中のフォルダ/ファイルの存在を確認
次は、DropboxのAPIを利用してフォルダ/ファイルの存在の確認を行います。フォルダ/ファイルの存在のチェックには、get_metadataを使用しています。get_metadataでは、フォルダ/ファイルが存在する場合は、フォルダ/ファイルに関するメタ情報が返され、存在しない場合は、HTTPコード409で、not_foundのエラーが返されます。
(1)では、アプリケーションの作成時に取得したアクセストークンを入力してください。(2)は存在の確認を行いたいフォルダ/ファイルのパスを設定してください。
<?php
$url ="https://api.dropboxapi.com/2/files/get_metadata";
$headers = array(
'Authorization: Bearer XXXXXXX', //(1)
'Content-Type: application/json'
);
$post = array(
"path" => "/test/"//(2)
);
$options = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($post),
);
$ch = curl_init();
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
var_dump(json_decode($result));
存在する場合
存在する場合は、下記のようなメタ情報が戻り値に入ります。
object(stdClass)#3067 (5)
{ [".tag"]=> string(6) "folder" ["name"]=> string(4) "test"
["path_lower"]=> string(5) "/test" ["path_display"]=> string(5)
"/test" ["id"]=> string(25) "id:2ozr6e1JbiAAAAAAow" }
存在しない場合
存在しないフォルダをパスに設定して、実行するとnot_foundのエラーメッセージが戻されます。
object(stdClass)#3067 (2)
{ ["error_summary"]=> string(15) "path/not_found/"
["error"]=> object(stdClass)#3064 (2)
{ [".tag"]=> string(4) "path"
["path"]=> object(stdClass)#3070 (1)
{ [".tag"]=> string(9) "not_found" } } }
curlのcurl_getinfoを使ってHTTPコードを確認すると存在した場合は、200。存在しない場合は、409が戻されます。HTTPコードを使用すれば存在の可否を判断することができます。
var_dump(curl_getinfo($ch, CURLINFO_HTTP_CODE));
Dropbox内での新規フォルダ作成
次は、DropboxのAPIを利用して、新しいフォルダの作成を行います。get_metadataを利用してフォルダの存在をチェックし、もし存在しない場合は新規でフォルダを作成するといったことが可能になります。
<?php
$url = "https://api.dropboxapi.com/2/files/create_folder_v2";
$headers = array(
'Authorization: Bearer XXXXXXX', //(1)
'Content-Type: application/json'
);
$post = array(
"path" => "/test/new_folder"//(2)
);
$options = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($post),
);
$ch = curl_init();
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
var_dump(json_decode($result));
実行後は、Dropboxにフォルダが作成されているかどうか確認を行ってください。変数$resultには、作成したフォルダの情報が入っています。
object(stdClass)#3067 (1)
{ ["metadata"]=> object(stdClass)#3064 (4)
{ ["name"]=> string(9) "new_folder"
["path_lower"]=> string(9) "/test/new_folder"
["path_display"]=> string(16) "/test/new_folder"
["id"]=> string(25) "id:2ozr6e1JbiAAAAAAArw" } }
エラーハンドリング
DropboxのAPIにアクセスした結果エラーが発生した場合にはresultにはerror_summary, errorを持つ情報が保存されます。下記の例は無効なアクセストークンを利用してアクセスを行った場合にresultに含まれる情報です。
"{"error_summary": "invalid_access_token/", "error": {".tag": "invalid_access_token"}}"
Dropbox上で正常に処理が行われた場合にはresultに含まれる内容はAPIのエンドポイントによって異なります。
正常に処理が行われたどうかはDropboxから戻されるステータスコードで確認することができます。正常に処理が行われた場合にはステータスコードは200が戻され、無効なアクセストークンの場合などには401が戻されます。
ステータスコードはcurl_getinfoで確認することができます。
$status_code = curl_getinfo($ch,CURLINFO_RESPONSE_CODE);
ステータスコードで分岐を行うことでエラーが発生した場合のみエラーの情報を取得することができます。
$status_code = curl_getinfo($ch,CURLINFO_RESPONSE_CODE);
if($status_code !== 200){
var_dump(json_decode($result)->error_summary);
}
ここまでの動作確認を行うことができれば社内やサーバ上にあるデータをどのようにDropboxに保存すればDropboxの容量を有効活用できるかなどのアイデアが浮かんでくるかと思います。本文書で覚えた技術を活用してDropboxを有効活用してください。