PHP8.2.0を使用してスプレッドシートの読み込み、書き込みを行う方法
何かの手順通りにやってみたところエラーが出て困ったので、解決方法を残しておきます
実行環境
windows10のxamppのlocalhost内に配置したphpファイルを、コマンドプロンプトから実行
読み込み、書き込みに使用した実際のソースコード
require_once __DIR__ . '/vendor/autoload.php';
$key = __DIR__ . '/API_KEY/independent-bay-xxxxxxxxxxx自分のファイルパスに書き換えてください。私はAPI_KEYフォルダの中に入れたので、こういうパスになっていますxxxxxxxxxxxxx.json';//取得したサービスキーのパスを指定
$client = new Google_Client();//Googleクライアントインスタンスを作成
$client->setScopes([//スコープを以下の内容でセット
\Google_Service_Sheets::SPREADSHEETS,
\Google_Service_Sheets::DRIVE,]);
$client->setAuthConfig($key);//サービスキーをセット
$sheet = new Google_Service_Sheets($client);//シートを操作するインスタンス
$sheet_id = 'xxxxxxxxxxx自分のスプレッドシートIDに書き換えてくださいxxxxxxxxxxxxxxxx';//対象のスプレッドシートのIDを指定
//取得範囲を指定(書き方: シート名+ビックリマーク+範囲の左上のセル+コロン+範囲の右下のセル)(data!A1:C3と書くと、dataというシートのセルA1~C3を指定したことになる)
//※自分のシート名と範囲に書き換えてください。私はシートの名前を「Sheet_spleadAPI」なので下記のようになっています。
$range = 'Sheet_spleadAPI!A1:C3';
//多分スプレッドシートにアクセスしている
$response = $sheet->spreadsheets_values->get($sheet_id, $range);
//返ってきたresponseから、セルの値(配列)を取得して、変数に格納
$values = $response->getValues();//帰ってきたresponseから値を取得
//取得したセルの値(配列)を表示してみる
print_r($values);
/*
print_r($values); の結果は下記のようにコマンドプロンプトに表示された。
※スプレッドシートには事前に"b"を書いて置いた
Array
(
[0] => Array
(
[0] => b
[1] => b
[2] => b
)
[1] => Array
(
[0] => b
[1] => b
[2] => b
)
[2] => Array
(
[0] => b
[1] => b
[2] => b
)
)
*/
//書き込み範囲を指定(書き方: シート名+ビックリマーク+範囲の左上のセル+コロン+範囲の右下のセル)(data!A1:C3と書くと、dataというシートのセルA1~C3を指定したことになる)
//必ず、書き込む内容の配列と同じ形にする。今回は2行3列のデータを書き込むので、A6:C7(2行3列)を指定している
$range = 'Sheet_spleadAPI!A6:C7';
//書き込む内容を配列にて指定指定
$values = [
["jog","dio","audi"],
["jog","dio","audi"]
];
//書き込む内容を収めた配列をbodyに格納
$body = new Google_Service_Sheets_ValueRange(['values' => $values]);
/*
いよいよシートの該当範囲に書き込む内容を反映します。
ValueInputOptionは値を書き込む際の形式指定で、
「RAWS」、もしくは「USER_ENTERED」のいずれかで指定します。
特にこだわりがない場合は「USER_ENTERED」で問題ありません。 (との事。)
*/
$sheet->spreadsheets_values->update($sheet_id, $range, $body, ["valueInputOption" => 'USER_ENTERED']);
下準備
Google Sheets APIを利用する準備
PHPでスプレッドシートの読み書きを行う場合、Google Sheets APIを使用することが一般的です。Google Sheets APIを使用するには、vendorをインストールする必要があるらしいので、
windows コマンドプロンプトにて、"phpファイルを置いてあるディレクトリに移動した後"、下記コマンドを実行する。
すると当該ディレクトリにvendorフォルダが作成される。(その中には沢山のphpファイル(API)が入っていました。)
composer require google/apiclient:"^2.0"
スプレッドシートにアクセスするためのAPIを有効化して、認証情報(.jsonファイル)をダウンロードしておく
下記記事にAPIの有効化方法と、認証情報(.jsonファイル)のダウンロード方法が書いてあります
https://sterfield.co.jp/programmer/google%E3%82%B9%E3%83%97%E3%83%AC%E3%83%83%E3%83%89%E3%82%B7%E3%83%BC%E3%83%88%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92php%E3%81%A7%E5%8F%96%E5%BE%97/
ダウンロードしたjsonファイルは、任意の場所に保存しておきましょう。
私はphpファイルと同じ階層に「API_KEY」というフォルダを作り、その中に入れました。
このjsonファイルのパスは、phpファイルに記述してください。
スプレッドシートの共有で(APIを利用するサービスアカウント? ※すみませんこのあたりはあまり理解していない)を招待する。
ダウンロードした認証情報(.jsonファイル)をテキストエディタで開くと、下記のようなメールアドレスがあります。
●●●●●●●●●@independent-bay-●●●●●●.iam.gserviceaccount.com
スプレッドシートを開いて、右上の「共有」を押して、[ユーザーやグループを追加]という入力フォームにメールアドレスを入れて、「編集者」を選択して、「送信」を押下。これだけでOK。
※メールを開いてクリックとかそういうのはいらない。「送信」を押すだけで、共有された事になりました
エラー解決方法
スプレッドシート書き込み時のエラー
PHP Fatal error: Uncaught TypeError: implode(): Argument #2 ($array) must be of type ?array, string given in C:\xampp\htdocs\youtube_live\php_spleadSheetAPI_test\vendor\google\apiclient\src\Google\Service\Resource.php:295
原因は、PHPの純正のimplode()メソッドの仕様変更によるものらしい。
下記サイトによると、引数の順番が変更になっている。
https://www.php.net/manual/ja/function.implode.php
//▼古い書き方。(エラーになる書き方)
implode(配列,文字列)
//▼新しい書き方
implode(文字列, 配列)
上記を直す為に、インストールしたvendor内にある下記のphpファイルを、下記のように書き換えます
▼書き換え前
if (count($queryVars)) {
$requestUrl .= '?' . implode($queryVars, '&');
}
▼書き換え後。以下のように修正すると、エラーが無くなり、スプレッドシートに書き込みが出来た。
修正内容:implode関数に渡されている引数の順番を逆にした。$queryVarsは配列だったので、第二引数に持ってきた。
if (count($queryVars)) {
$requestUrl .= '?' . implode('&', $queryVars);
}
スプレッドシート読み込みする時に出るエラー
Fatal error: Uncaught TypeError: count():
これを解消する方法は下記です。インストールしたvendor内にある下記のphpファイルを書き換えます
public function release(EasyHandle $easy)
{
$resource = $easy->handle;
unset($easy->handle);
//以下の1行をコメントアウトしました。
//if (count($this->handles) >= $this->maxHandles) {
//以下の1行を追加しました
if(count((array)$this-> handles) >= $this-> maxHandles){
curl_close($resource);
} else {
// Remove all callback functions as they can hold onto references
// and are not cleaned up by curl_reset. Using curl_setopt_array
// does not work for some reason, so removing each one
// individually.
curl_setopt($resource, CURLOPT_HEADERFUNCTION, null);
curl_setopt($resource, CURLOPT_READFUNCTION, null);
curl_setopt($resource, CURLOPT_WRITEFUNCTION, null);
curl_setopt($resource, CURLOPT_PROGRESSFUNCTION, null);
curl_reset($resource);
$this->handles[] = $resource;
}
}
(参考ページ:https://qiita.com/Takahiro_Inoway/items/fb2c847a23e7ff039840)
まとめ
上記2つのphpファイルを修正した事により、
PHPにてスプレッドシートのとある範囲の読み込みと、
PHPにてスプレッドシートのとある範囲への書き込みが出来ました。
▼PHPプログラム実行前のスプレッドシートの状態(読み込み予定のセルに ひらがな を入れておきました)