Firestore でのセッション処理

このチュートリアルでは、App Engine でセッションを処理する方法を説明します。

多くのアプリには、認証設定とユーザー設定用のセッション処理が必要です。PHP には、この機能を実行するためのメモリベースの実装が付属しています。ただし、記録されるセッションがインスタンス間で異なる場合があるため、この実装は複数のインスタンスにサービスを提供できるアプリには適しません。

目標

  • アプリを作成する。
  • アプリをローカルで実行する。
  • App Engine にアプリをデプロイする。

料金

このチュートリアルでは、課金対象である次の Google Cloud コンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。新しい Google Cloud ユーザーは無料トライアルをご利用いただけます。

このチュートリアルを終了した後、作成したリソースを削除すると、それ以上の請求は発生しません。詳しくは、クリーンアップをご覧ください。

始める前に

  1. Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。

  2. Cloud Console のプロジェクト セレクタページで、Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタのページに移動

  3. Google Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトに対して課金が有効になっていることを確認する方法を学習する

  4. Firestore API を有効にします。

    API を有効にする

  5. Cloud SDK をインストールして初期化します。
  6. 新しい Google Cloud プロジェクトを使用するように gcloud ツールを構成します。
    # Configure gcloud for your project
    gcloud config set project PROJECT_ID
    PROJECT_ID を以前に作成または選択した Google Cloud プロジェクト ID に置き換えます。

プロジェクトの設定

  1. ターミナル ウィンドウで、選択したディレクトリに移動し、sessions という名前の新しいディレクトリを作成します。このチュートリアルのコードはすべて、sessions ディレクトリ内にあります。

  2. sessions ディレクトリに移動します。

    cd sessions
    
  3. 依存関係をインストールします。

    composer require google/cloud-firestore
    

このチュートリアルの最後では、最終的なファイル構造が次のようになります。

sessions
├── app.yaml
└── composer.json
├── index.php

アプリを作成する

  • ターミナル ウィンドウで、次の内容の index.php という名前のファイルを作成します。

    <?php
    /*
     * Copyright 2019 Google LLC
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    require_once __DIR__ . '/vendor/autoload.php';
    
    use Google\Cloud\Firestore\FirestoreClient;
    
    $projectId = getenv('GOOGLE_CLOUD_PROJECT');
    // Instantiate the Firestore Client for your project ID.
    $firestore = new FirestoreClient([
        'projectId' => $projectId,
    ]);
    
    $handler = $firestore->sessionHandler(['gcLimit' => 500]);
    
    // Configure PHP to use the the Firebase session handler.
    session_set_save_handler($handler, true);
    session_save_path('sessions');
    session_start();
    
    $colors = ['red', 'blue', 'green', 'yellow', 'pink'];
    /**
     * This is an example of a front controller for a flat file PHP site. Using a
     * Static list provides security against URL injection by default.
     */
    switch (@parse_url($_SERVER['REQUEST_URI'])['path']) {
        case '/':
            if (!isset($_SESSION['views'])) {
                $_SESSION['views'] = 0;
                $_SESSION['color'] = $colors[rand(0, 4)];
            }
            printf(
                '<body bgcolor="%s">Views: %s</body>',
                $_SESSION['color'],
                $_SESSION['views']++
            );
            break;
        default:
            http_response_code(404);
            exit('Not Found');
    }
    

このアプリは、ユーザーごとに異なる言語で挨拶を表示します。リピーターは常に同じ言語で挨拶されます。

さまざまな言語で挨拶が表示されている複数のアプリ ウィンドウ。

アプリでユーザーの設定を保存するには、現在のユーザーに関する情報をセッションに保存する方法が必要です。このサンプルアプリは、Firestore を使用してセッション データを保存します。

PHP セッション用に Firestore を使用するには、Firestore session handler を使用します。

次の図は、Firestore が App Engine アプリ用のセッションを処理する方法を示しています。

アーキテクチャの図: ユーザー、App Engine、Firestore。

session_set_save_handler を設定すると、セッションにアクセスするために使用可能な $_SESSION グローバル変数がすべてのリクエストに含まれます。セッション データは Firestore に保存されます。

ローカルでの実行

  1. 組み込みの PHP ウェブサーバーを起動します。

    php -S localhost:8080
    
  2. ウェブブラウザでアプリを表示します。

    Cloud Shell

    Cloud Shell ツールバーの [ウェブでプレビュー] ウェブでプレビュー アイコンをクリックし、[ポート 8080 でプレビュー] を選択します。

    ローカルマシン

    ブラウザで、http://localhost:8080 にアクセスします。

    「Hello World」、「Hallo Welt」、「Hola mundo」、「Salut le Monde」、「Ciao Mondo」の 5 つの挨拶のいずれかが表示されます。別のブラウザまたはシークレット モードでページを開くと、別の言語で表示されます。セッション データは Google Cloud Console で表示して編集できます。

    Cloud Console の Firestore セッション。

  3. HTTP サーバーを停止するには、ターミナル ウィンドウで Control+C を押します。

App Engine でのデプロイと実行

App Engine スタンダード環境を使用すると、高い負荷の下で大量のデータを使用して正常に動作するアプリをビルドしてデプロイできます。

このチュートリアルでは、App Engine スタンダード環境を使用してサーバーをデプロイします。

  1. ターミナル ウィンドウで app.yaml ファイルを作成し、以下をコピーします。

    runtime: php73
    
  2. App Engine にアプリをデプロイします。

    gcloud app deploy
    
  3. ライブのアプリを表示するには、次の URL を入力します。

    https://PROJECT_ID.REGION_ID.r.appspot.com

    以下を置き換えます。

これで、App Engine インスタンスで実行しているウェブサーバーから挨拶が配信されます。

セッションの削除

PHP は、セッションのガベージ コレクション(GC)を実行します。これにより、php.ini 設定に従って、古いセッションと期限切れのセッションが削除されます。デフォルトでは、Firestore セッション ハンドラはセッションをクリーンアップしません。ただし、セッション ハンドラの作成時に gcLimit オプションを渡すことによって、クリーンアップするように構成できます。

$handler = $firestore->sessionHandler(['gcLimit' => 500]);

セッションは、確率ベースのセッション GC を使用して削除されます。または、session_gc 関数を明示的に呼び出した場合に削除されます。

アプリのデバッグ

App Engine アプリに接続できない場合は、次の点を確認してください。

  1. gcloud デプロイ コマンドが正常に終了して、エラーを出力しなかったことを確認します。エラー(message=Build failed など)が発生した場合は、それらを修正してから、もう一度、App Engine アプリのデプロイを試みます。
  2. Cloud Console で、[ログビューア] ページに移動します。

    [ログビューア] ページに移動

    1. [最近選択したリソース] プルダウン リストで、[App Engine アプリケーション] をクリックしてから、[All module_id] をクリックします。アプリにアクセスした以降のリクエストのリストが表示されます。リクエストのリストが表示されない場合は、プルダウン リストで [All module_id ] が選択されていることを確認します。エラー メッセージが Cloud Console に出力された場合は、アプリのコードがウェブアプリの作成に関するセクション内のコードと一致することを確認します。

    2. Firestore API が有効になっていることを確認します。

クリーンアップ

プロジェクトの削除

  1. Cloud Console で [リソースの管理] ページに移動します。

    [リソースの管理] ページに移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

App Engine インスタンスの削除

  1. Cloud Console で、App Engine の [バージョン] ページに移動します。

    [バージョン] ページに移動

  2. デフォルト以外で削除するアプリのバージョンのチェックボックスをオンにします。
  3. [削除] をクリックして、アプリのバージョンを削除します。

次のステップ