LoginSignup
2
1

More than 3 years have passed since last update.

Amazon DynamoDBでphpのセッションを管理する

Last updated at Posted at 2020-11-30

はじめに

AWS DynamoDBでphpのセッションを管理します。
マルチAZの場合、複数のEC2でセッション情報を同期する必要があります。

その場合、候補に上がるのが、 DynamoDBかElastiCacheになるはずです。

1. IAMポリシーの作成
EC2インスタンスにアタッチしているロールに、このポリシーを割り当てます。

php-sessions
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:GetItem",
                "dynamodb:UpdateItem",
                "dynamodb:DeleteItem",
                "dynamodb:Scan",
                "dynamodb:BatchWriteItem"
            ],
            "Resource": "arn:aws:dynamodb:ap-northeast-1:{AWSのアカウントID}:table/{DynamoDBのテーブル名}"
        }
    ]
}

2. DynamoDBの作成
DynamoDBを作成します。

項目
テーブル名 任意
プライマリキー id (文字列)

テーブル作成後、「概要->TTLの管理」から、 TTLを有効化にします。

項目
TTL属性 expired (任意)

3. EC2インスタンスにphpのSDKをインストールする
EC2インスタンスにcomposerを利用して、phpのSDKをインストールします。

:スクリプト
# composer設定
EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)"
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"

if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]
then
    >&2 echo 'ERROR: Invalid installer signature'
    rm composer-setup.php
    exit 1
fi

php composer-setup.php --quiet
RESULT=$?
rm composer-setup.php

sudo mv composer.phar /usr/local/bin/composer
sudo yum install -y --enablerepo=remi,remi-php70 php-xml
sudo rm composer*
composer require aws/aws-sdk-php

4. phpからの利用方法
セッション管理用のクラスを作成します。
シングルトンパターンを利用します。

SessionDynamoDB.php
<?php

# 任意のディレクトリに配置したautoload.phpを呼び出す
require_once(dirname(__FILE__) . '/autoload.php');

use Aws\DynamoDb\DynamoDbClient;
use Aws\DynamoDb\SessionHandler;
use Aws\DynamoDb\Exception\DynamoDbException;

interface SessionDynamoDBInterface
{
    //インスタンスを生成する。
    public static function getInstance();

    //ハンドラーを登録する。
    public function start();
}

class SessionDynamoDB implements SessionDynamoDBInterface
{

    private static $singleton;
    private $client;
    private $sessionHandler;

    /**
     * DynamoDBクライアント生成
     */
    private function __construct()
    {
        try {
            $this->client = DynamoDbClient::factory([
                'region' => 'ap-northeast-1',
                'version' => 'latest',
            ]);

            $this->sessionHandler = SessionHandler::fromClient($this->client, [
                'table_name'               => '{DynamoDBのテーブル名}',
                'hash_key'                 => 'id',
                'session_lifetime'         => 3600,
                'consistent_read'          => true,
                'locking'                  => false,
                'batch_config'             => [],
                'max_lock_wait_time'       => 10,
                'min_lock_retry_microtime' => 5000,
                'max_lock_retry_microtime' => 50000,
            ]);
            $this->sessionHandler->register();

            // Start the session
            session_start();

            // // Close the session (optional, but recommended)
            session_write_close();

        } catch(DynamoDbException $e){
            throw new DynamoDbException ($e->getMessage());
        }
    }

    /**
     * インスタンスを生成する。
     *
     * @return object self::$singleton
     */
    public static function getInstance(): object
    {
        if (!isset(self::$singleton)) {
            self::$singleton = new SessionDynamoDB();
        }
        return self::$singleton;
    }

    /**
     * このインスタンスの複製を許可しないようにする
     *
     * @throws RuntimeException
     */
    public final function __clone()
    {
        throw new RuntimeException ('Clone is not allowed against ' . get_class($this));
    }

    /**
     * ハンドラーを登録する。
     *
     */
    public function start(): void
    {
        $this->sessionHandler->register();

        // Start the session
        session_start();
    }

}

クラスからセッションを利用します。

php実行ファイル
# 任意のディレクトリに配置したSessionDynamoDB.phpを呼び出す
require_once(dirname(__FILE__) . '/SessionDynamoDB.php');

$session = SessionDynamoDB::getInstance();
$session->start();

# 冒頭に上記の記述をすれば、あとは普通に$_SESSIONを利用するだけです。
var_dump($_SESSION);

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1