Edited at

Google App Engine for PHPでGoogle Drive APIを使う

More than 3 years have passed since last update.

Google App Engine for PHP(GAE/PHP)では残念ながらBlobstoreの利用がサポートされていません。そこでGoogleが提供しているGoogle DriveとAPIライブラリを用いてGAE/PHPからGoogle Driveへアクセスしてみます。

(2016.07.07 Google Cloud Platformが刷新されたため情報が古くなっています)


1. API利用設定

Developers Consoleへアクセスし、APIの設定からDrive APIを有効にします。


2. OAuthの設定

Developers Consoleの[認証情報]からOAuth認証によるクライアントIDの取得を行います。[新しいクライアントIDを作成]ボタンを押すと設定画面が表示されます。アプリケーションの種類は[ウェブアプリケーション]を選択し、[同意画面を設定]ボタンを押します。

同意画面でサービス名に任意の値を記入して[保存]ボタンを押します。

クライアントID作成画面に戻ります。承認済みのリダイレクトURIを入力するフォームにはOAuth認証後に戻ってくるURLを入力します。

[クライアントIDを作成]ボタンを押すとクライアントIDが作成されます。



これから作成するプロジェクトはこのクライアントID、クライアントシークレット、リダイレクトURIを使用します。


3. Google APIs Client Library for PHPのダウンロード

PHPからGoogleのAPIへアクセスするためのライブラリをダウンロードします。ライブラリはGoogleが提供している下記のリンクからダウンロードすることができます。APIに関する情報やリファレンスはDevelopers Documentationが参考になります。

google/google-api-php-client · GitHub

ダウンロードしたライブラリをプロジェクトファイルと同じフォルダに保存します。


4. プログラム


4.1 OAuth認証

Google Drive APIへのアクセスはOAuth認証を必要とします。2. OAuthの設定で取得したクライアントID、クライアントシークレット、リダイレクトURIを下記のサンプルに記述します。


sample.php

<?php

// ライブラリ読み込み
require_once('./google-api-php-client/src/Google/autoload.php');

// セッションスタート
session_start();
$client = new Google_Client();
// クライアントID
$client->setClientId('クライアントID');
// クライアントシークレット
$client->setClientSecret('クライアントシークレット');
// リダイレクトURI
$client->setRedirectUri('リダイレクトURI');

// 許可されてリダイレクトされると URL に code が付加されている
// code があったら受け取って、認証する
if (isset($_GET['code'])) {
// 認証
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
// リダイレクト GETパラメータを見えなくするため(しなくてもOK)
header('Location: http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']);
exit;
}

// セッションからアクセストークンを取得
if (isset($_SESSION['token'])) {
// トークンセット
$client->setAccessToken($_SESSION['token']);
}

// トークンがセットされていたら
if ($client->getAccessToken()) {
try {
echo "Google Drive Api 連携完了!<br>";
$_SESSION['client'] = $client;
} catch (Google_Exception $e) {
echo $e->getMessage();
}
} else {
// 認証用URL取得
$client->setScopes(Google_Service_Drive::DRIVE);
$authUrl = $client->createAuthUrl();
echo '<a href="'.$authUrl.'">アプリケーションのアクセスを許可してください。</a>';
exit;
}

?>
<a href="list.php">ファイル一覧</a><br>
<a href="imageview.php">画像表示</a><br>
<a href="upload.php">アップロード</a>



4.2 ファイル一覧

Google Driveに保存されているファイルの一覧を取得します。


list.php

<?php

require_once('./google-api-php-client/src/Google/autoload.php');
require_once('./google-api-php-client/src/Google/Service/Drive.php');
//$client変数の型を明示させるためsession_start()はライブラリ読み込みの後に記述
session_start();

$client = $_SESSION['client'];
$service = new Google_Service_Drive($client);

try {
// 親フォルダ
// root でマイドライブ, root 以外は名前ではなく ID を指定
$parents = 'root';
if (isset($_GET['parents'])) {
$parents = htmlspecialchars($_GET['parents'], ENT_QUOTES);
}
// 次ページに移動する場合に渡すトークン
$pageToken = null;
if (isset($_GET['pageToken'])) {
$pageToken = $_GET['pageToken'];
}
$parameters = array('q' => "'{$parents}' in parents", 'maxResults' => 20);
if ($pageToken) {
$parameters['pageToken'] =$pageToken;
}
// ファイルリスト取得, Google_Service_Drive_FileList のオブジェクトが返ってくる
$files = $service->files->listFiles($parameters);
// ファイルの一覧データ
$results = $files->getItems();
// 次ページのトークン取得, ない場合は NULL
$pageToken = $files->getNextPageToken();
// 結果表示
foreach ($results as $result) {
if ($result->mimeType == 'application/vnd.google-apps.folder') {
echo 'フォルダ :<a href="http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'?parents='.urlencode($result->id).'">'.$result->title.'</a> ID:'.$result->id.'<br />';
} else {
echo 'ファイル :<a href="read.php?id='.$result->id.'"">'.$result->title.'</a> ID:'.$result->id.'<br />';
}
}
// pageToken があったら次ページヘのリンク表示
if ($pageToken) {
echo '<a href="http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'?parents='.urlencode($parents).'&pageToken='.urlencode($pageToken).'">次ページ</a>';
}
}catch(Google_Exception $e){
echo $e->getMessage();
}



4.3 画像表示

Google Driveに保存してある画像を表示するプログラムです。


imageview.php

<?php

require_once('./google-api-php-client/src/Google/autoload.php');
require_once('./google-api-php-client/src/Google/Service/Drive.php');

session_start();

$client = $_SESSION['client'];
$service = new Google_Service_Drive($client);

try {
// 親フォルダ
// root でマイドライブ, root 以外は名前ではなく ID を指定
$parents = 'root';
if (isset($_GET['parents'])) {
$parents = htmlspecialchars($_GET['parents'], ENT_QUOTES);
}
// 次ページに移動する場合に渡すトークン
$pageToken = null;
if (isset($_GET['pageToken'])) {
$pageToken = $_GET['pageToken'];
}
$parameters = array('q' => "'{$parents}' in parents", 'maxResults' => 20);
if ($pageToken) {
$parameters['pageToken'] =$pageToken;
}
// ファイルリスト取得, Google_Service_Drive_FileList のオブジェクトが返ってくる
$files = $service->files->listFiles($parameters);
// ファイルの一覧データ
$results = $files->getItems();
// 次ページのトークン取得, ない場合は NULL
$pageToken = $files->getNextPageToken();
// 結果表示
foreach ($results as $result) {
// 拡張子がjpgであれば表示
if ($result->fileExtension == 'jpg') {
echo "<img border=0 src={$result->webContentLink}><img border=0 src={$result->thumbnailLink}><br>";
}
}
// pageToken があったら次ページヘのリンク表示
if ($pageToken) {
echo '<a href="http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'?parents='.urlencode($parents).'&pageToken='.urlencode($pageToken).'">次ページ</a>';
}
}catch(Google_Exception $e){
echo $e->getMessage();
}


マイドライブの直下であれば親フォルダはroot、フォルダを指定する場合はフォルダIDを設定します。フォルダIDは4.2 ファイル一覧か、ブラウザでGoogle Driveへアクセスし対象のフォルダを選択するとURLからIDを確認することができます。

https://drive.google.com/drive/#folders/{フォルダID}

またファイルはFilesで確認できるように拡張子、サムネイルリンク、web参照リンクなどを返すメソッドが用意されています。サンプルではファイル拡張子のjpgを判断して表示させています。


4.4 アップロード

ファイルのアップロードはinsertメソッドを使用します。注意点としてinsertメソッドの第2引数のarray()には 'uploadType' => 'multipart'を記述しないと空のファイルが作成されてしまいます。


upload.php

<?php

require_once('./google-api-php-client/src/Google/autoload.php');
require_once('./google-api-php-client/src/Google/Service/Drive.php');
//session_start()はライブラリ読み込みの後に記述
session_start();

$client = $_SESSION['client'];
$service = new Google_Service_Drive($client);

// 追加したいファイルオブジェクトを作成
$file = new Google_Service_Drive_DriveFile();
$file->setTitle('new_test.txt');
$file->setDescription('PhpTest');
$file->setMimeType('text/plain');

$data = 'aaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccc';
//$data = file_get_contents("./new_test.txt");

// 親フォルダの ID
$parentId = 'root';
// 親オブジェクト
$parent = new Google_Service_Drive_ParentReference();
$parent->setId($parentId);
$file->setParents(array($parent));

try {
$result = $service->files->insert($file, array(
'data' => $data,
'mimeType' => 'text/plain',
'uploadType' => 'multipart'
));

if($result) {
echo "アップロード完了";
} else {
echo "アップロード失敗";
}
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}



4.5 ファイルの読み込み

テキストファイルの内容を読み込みます。


read.php

<?php

require_once('./google-api-php-client/src/Google/autoload.php');
require_once('./google-api-php-client/src/Google/Service/Drive.php');
session_start();

$client = $_SESSION['client'];
$service = new Google_Service_Drive($client);
$id = $_GET['id'];

echo "ファイルID:{$id}<br>";

try {
$file = $service->files->get($id);
$downloadUrl = $file->getDownloadUrl();
$request = new Google_Http_Request($downloadUrl, 'GET', null, null);
$httpRequest = $service->getClient()->getAuth()->authenticatedRequest($request);
if ($httpRequest->getResponseHttpCode() == 200) {
echo "ファイル内容<br>";
echo $httpRequest->getResponseBody();
} else {
// An error occurred.
return null;
}
} catch(Google_Exception $e) {
echo $e->getMessage();
}


参考

PHPでGoogle Drive Apiを使用する | ScrapEngineer

[PHP] Google Drive API を使って Google Drive のファイル一覧取得、ファイルの追加を行う | unlinked log

Google Developers