googleスプレッドシートをPHPからアクセスしたら超絶めんどくさかった件

エクセルのシートをPHPで読みたかったのですが、googleスプレッドシート経由で読めば簡単じゃね?
と思ってやり始めたときのメモです。

公式のチュートリアルを見て簡単じゃーんと思ったのですが・・・結果としては、結構ハマりました。

全体の流れ

まず必要な作業としてはいかの手順になります。
1.Google Developers Consoleを登録
2.Google Developers ConsoleでAPIキーとサービスアカウントの作成する
3.アクセスするシートを作ってアクセス権を設定する
4.composerでライブラリを導入
5.プログラムの作成

今回ハマった点は、Google Developers Consoleとかアクセス権回り。
その辺りは、他のAPIも含めて全体的に同じなので省略されていて、特定のサービスのチュートリアルには何にも書いていないため、かいつまんで読んでいるだけではさっぱりわからんという状態になります。

スポンサーリンク

1.Google Developers Consoleを登録

https://console.developers.google.com
Googleアカウントが必要です。また、Google Developers Consoleは有料なのでクレジットカードの登録が必要です。
新規アカウントの場合は無料トライアルがあるので、ちょっと試す分には大丈夫かとおもいます。

2.Google Developers Consoleでサービスアカウントを作成する。

次にサービスアカウントを作成します。
認証情報->認証情報を作成からサービス アカウント キーを選択
サービスアカウントを作成と出るので、適当な名前を付けて役割を選択、キーのタイプをJSONを選択して作成します。
すると、テキストファイルがダウンロードされます。後で使うので保存しておきましょう。

3.アクセスするシートを作ってアクセス権を設定する

適当にシートを作っておきましょう。
https://www.google.com/intl/ja_jp/sheets/about/

シートを開くとこんな感じのURLになるかと思います。
https://docs.google.com/spreadsheets/d/{シートのID}/edit#gid=0
{シートのID}の部分の文字列をメモしておきましょう。

次にアクセス権を設定します。
前の項目で保存したファイルの中に”client_email”という項目があり”?????????????.iam.gserviceaccount.com”といった感じでメールアドレスが書いてあるかと思いますので、このアドレスを共有ユーザーとして登録します。

4.composerでライブラリを導入

google謹製のライブラリをインストール

composer require google/apiclient:^2.0

5.プログラムの作成

では読み書きをしてみましょう。
まず、2で取得したファイルをprivate_key.jsonというファイル名にしてPHPファイルと同じ場所に置きます。

    require_once 'vendor/autoload.php';
    putenv("GOOGLE_APPLICATION_CREDENTIALS=private_key.json");
    $client = new Google_Client();
    var_dump(getenv("GOOGLE_APPLICATION_CREDENTIALS"));

    $seet_id = "シートのID";

    $client->setApplicationName("sheet read");
    $client->useApplicationDefaultCredentials();    //GOOGLE_APPLICATION_CREDENTIALSを読みこみ
    $client->addScope(Google_Service_Sheets::SPREADSHEETS);
    
    $service = new Google_Service_Sheets($client);
    // A1:A2 を更新
    $value = new Google_Service_Sheets_ValueRange();
    $value->setValues([ 'values' => [ 'hoge', 'fuga' ] ]);
    $response = $service->spreadsheets_values->update($seet_id, 'シート1!A1', $value, [ 'valueInputOption' => 'USER_ENTERED' ] );
    $value->setValues([ 'values' => [ 'hoge2', 'fuga2' ] ]);
    $response = $service->spreadsheets_values->update($seet_id, 'シート1!A2', $value, [ 'valueInputOption' => 'USER_ENTERED' ] );

    // A1:B4 の範囲を取得
    $response = $service->spreadsheets_values->get($seet_id, 'シート1!A1:B4');
    foreach ($response->getValues() as $index => $cols) {
        echo sprintf('#%d >> "%s"', $index+1, implode('", "', $cols)).PHP_EOL;
    }

基本的にスプレッドシートを特定するスプレッドシートID、シートの名称:セルの範囲をしていするひつようがあります。
設定は$service->spreadsheets_values->updateで、スタート地点のセルを設定して、1行ごとに更新可能
取得はspreadsheets_values->getメソッドで行え、第2引数で指定したセルの範囲で行ごとに配列で取得できます。
計算式もちゃんと反映されますし、計算式自体も書き込めるようです。

なんだかんだでここまで理解するので1日かかってしまった。