Symfoware

Symfowareについての考察blog

AWS PHP(CodeIgniter 3)のセッションストレージにDynamoDBを使用する

CodeIgniterのセッション保持にDynamoDBを使用してみます。

こちらを参考にさせていただきました。
PHPアプリケーションのセッション管理にAmazon DynamoDBを使う


DynamoDB



管理コンソールから、「DynamoDB」をクリック。

606_01.png


「Create Tables」をクリック。

606_02.png

Table Nameに「session」
Primary Keyは「Hash」を選択し、String型で「id」という名前を指定します。

606_03.png


Add Indexesは特に指定しませんでした。

606_04.png


キャパシティの設定もデフォルトのまま。

606_05.png


アラートは未設定としました。

606_06.png


最終確認画面です。
「Create」でテーブルが作成されます。

606_07.png


sessionという名前のテーブルが作成されました。

606_08.png






DynamoDBの使い方



セッションドライバーを実装する前に、DynamoDBへのアクセス方法を見てみます。

aws-sdkのインストールと、CodeIgniterでの使用はこちら。
EC2 + PHPで構築したサイトにアップロードしたファイルをAmazonS3に保存する


参考にしたマニュアルはこちら。
Amazon DynamoDB


登録、データ取得、削除のサンプルはこのようになりました。


  1. <?php
  2. use Aws\DynamoDb\DynamoDbClient;
  3. use Aws\DynamoDb\Enum\Type;
  4. use Aws\DynamoDb\Enum\AttributeAction;
  5. // dynamoに接続するためのオブジェクトを作成
  6. $dynamo = DynamoDbClient::factory(array(
  7.     'region' => 'ap-northeast-1',
  8.     'key' => 'API_KEY',
  9.     'secret' => 'SECRET_KEY'
  10. ));
  11. // --- データの登録 ---
  12. // id:test_id, data(名前は任意):test_data
  13. $args = array(
  14.     'TableName' => 'session',
  15.     'Item' => $dynamo->formatAttributes(
  16.         array(
  17.             'id' => 'test_id',
  18.             'data' => 'test_data'
  19.         )
  20.     )
  21. );
  22. // putItemで登録実行
  23. $dynamo->putItem($args);
  24. // --- データの取得 ---
  25. // id:test_idのデータを取得
  26. $args = array(
  27.     'TableName' => 'session',
  28.     'Key' => array(
  29.         'id' => array(Type::STRING => 'test_id')
  30.     ),
  31.     'ConsistentRead' => true
  32. );
  33. // getItemでデータ取得
  34. $result = $dynamo->getItem($args);
  35. // dataという項目を取得するにはこんな感じ
  36. $data = $result['Item']['data'][Type::STRING];
  37. // --- データの削除 ---
  38. $args = array(
  39.     'TableName' => 'session',
  40.     'Key' => array(
  41.         'id' => array(Type::STRING => 'test_id')
  42.     ),
  43.     'ConsistentRead' => true
  44. );
  45. $dynamo->deleteItem($args);








CodeIgniterのセッションドライバー



system/libraries/Session/drivers/Session_memcached_driver.phpを参考に、
DynamoDBにセッションを保持するクラスを書いてみます。

※動くか確かめたかったので、エラー処理は適当です。
また、テーブル名なども固定うちです


・Session_dynamo_driver.php


  1. <?php
  2. defined('BASEPATH') OR exit('No direct script access allowed');
  3. /**
  4. * CodeIgniter Session Dynamo Driver
  5. *
  6. */
  7. use Aws\DynamoDb\DynamoDbClient;
  8. use Aws\DynamoDb\Enum\Type;
  9. use Aws\DynamoDb\Enum\AttributeAction;
  10. class CI_Session_dynamo_driver extends CI_Session_driver implements SessionHandlerInterface {
  11.     /**
  12.      * Dynamo instance
  13.      *
  14.      */
  15.     protected $_dynamo;
  16.     /**
  17.      * Key prefix
  18.      *
  19.      * @var    string
  20.      */
  21.     protected $_key_prefix = 'ci_session:';
  22.     // ------------------------------------------------------------------------
  23.     /**
  24.      * Class constructor
  25.      *
  26.      * @param    array    $params    Configuration parameters
  27.      * @return    void
  28.      */
  29.     public function __construct(&$params)
  30.     {
  31.         parent::__construct($params);
  32.         if (empty($this->_config['save_path']))
  33.         {
  34.             log_message('error', 'Session: No Memcached save path configured.');
  35.         }
  36.         if ($this->_config['match_ip'] === TRUE)
  37.         {
  38.             $this->_key_prefix .= $_SERVER['REMOTE_ADDR'].':';
  39.         }
  40.     }
  41.     // ------------------------------------------------------------------------
  42.     /**
  43.      * Open
  44.      *
  45.      * Sanitizes save_path and initializes connections.
  46.      *
  47.      * @param    string    $save_path    Server path(s)
  48.      * @param    string    $name        Session cookie name, unused
  49.      * @return    bool
  50.      */
  51.     public function open($save_path, $name)
  52.     {
  53.         
  54.         $this->_dynamo = DynamoDbClient::factory(array(
  55.             'region' => 'ap-northeast-1',
  56.             'key' => 'API_KEY',
  57.             'secret' => 'SECRET_KEY'
  58.         ));
  59.         return TRUE;
  60.     }
  61.     // ------------------------------------------------------------------------
  62.     /**
  63.      * Read
  64.      *
  65.      * Reads session data and acquires a lock
  66.      *
  67.      * @param    string    $session_id    Session ID
  68.      * @return    string    Serialized session data
  69.      */
  70.     public function read($session_id)
  71.     {
  72.         
  73.         if ( !isset($this->_dynamo)) {
  74.             return FALSE;
  75.         }
  76.         
  77.         $this->_session_id = $session_id;
  78.         
  79.         $args = array(
  80.             'TableName' => 'session',
  81.             'Key' => array(
  82.                 'id' => array(Type::STRING => $this->_key_prefix.$session_id)
  83.             ),
  84.             'ConsistentRead' => true
  85.         );
  86.         
  87.         $session_data_base = $this->_dynamo->getItem($args);
  88.         $session_data = $session_data_base['Item']['data'][Type::STRING];
  89.         
  90.         $this->_fingerprint = md5($session_data);
  91.         return $session_data;
  92.         
  93.     }
  94.     // ------------------------------------------------------------------------
  95.     /**
  96.      * Write
  97.      *
  98.      * Writes (create / update) session data
  99.      *
  100.      * @param    string    $session_id    Session ID
  101.      * @param    string    $session_data    Serialized session data
  102.      * @return    bool
  103.      */
  104.     public function write($session_id, $session_data)
  105.     {
  106.         
  107.         if ( !isset($this->_dynamo)) {
  108.             return FALSE;
  109.         }
  110.         
  111.         // Was the ID regenerated?
  112.         elseif ($session_id !== $this->_session_id)
  113.         {
  114.             $this->_fingerprint = md5('');
  115.             $this->_session_id = $session_id;
  116.         }
  117.         
  118.         $args = array(
  119.             'TableName' => 'session',
  120.             'Item' => $this->_dynamo->formatAttributes(
  121.                 array(
  122.                     'id' => $this->_key_prefix.$session_id,
  123.                     'data' => $session_data
  124.                 )
  125.             )
  126.         );
  127.         
  128.         $this->_dynamo->putItem($args);
  129.         
  130.         return TRUE;
  131.     }
  132.     // ------------------------------------------------------------------------
  133.     /**
  134.      * Close
  135.      *
  136.      * Releases locks and closes connection.
  137.      *
  138.      * @return    bool
  139.      */
  140.     public function close()
  141.     {
  142.         if (isset($this->_dynamo))
  143.         {
  144.             $this->_dynamo = NULL;
  145.         }
  146.         return True;
  147.     }
  148.     // ------------------------------------------------------------------------
  149.     /**
  150.      * Destroy
  151.      *
  152.      * Destroys the current session.
  153.      *
  154.      * @param    string    $session_id    Session ID
  155.      * @return    bool
  156.      */
  157.     public function destroy($session_id)
  158.     {
  159.         
  160.         if ( !isset($this->_dynamo)) {
  161.             return FALSE;
  162.         }
  163.         
  164.         $args = array(
  165.             'TableName' => 'session',
  166.             'Key' => array(
  167.                 'id' => array(Type::STRING => $this->_key_prefix.$session_id)
  168.             ),
  169.             'ConsistentRead' => true
  170.         );
  171.         
  172.         $this->_dynamo->deleteItem($args);
  173.         return $this->_cookie_destroy();
  174.     }
  175.     // ------------------------------------------------------------------------
  176.     /**
  177.      * Garbage Collector
  178.      *
  179.      * Deletes expired sessions
  180.      *
  181.      * @param    int     $maxlifetime    Maximum lifetime of sessions
  182.      * @return    bool
  183.      */
  184.     public function gc($maxlifetime)
  185.     {
  186.         // Not necessary, Dynamo takes care of that.
  187.         return TRUE;
  188.     }
  189. }





このファイルをapplication/libraries/Session/drivers/Session_dynamo_driver.phpに保存。
application/config/config.phpでこのドライバーを使用するよう指定します。

具体的には、sess_driverの項目に「dynamo」を指定。


  1. $config['sess_driver'] = 'dynamo';
  2. $config['sess_cookie_name'] = 'ci_session';
  3. $config['sess_expiration'] = 7200;
  4. $config['sess_save_path'] = 'session';
  5. $config['sess_match_ip'] = FALSE;
  6. $config['sess_time_to_update'] = 300;
  7. $config['sess_regenerate_destroy'] = FALSE;





こんなサンプルで確認します。


  1. <?php
  2. class Sample extends CI_Controller {
  3.     public function index() {
  4.         
  5.         // sessionライブラリをロード    
  6.         $this->load->library('session');
  7.         
  8.         // セッションデータ取得
  9.         $count = intval($this->session->userdata('count'));
  10.         
  11.         // カウントアップして保存
  12.         $this->session->set_userdata(array('count' => $count + 1));
  13.         
  14.         echo $count;
  15.     }
  16.     
  17.     
  18. }




リロードするたびにカウントアップされます。

606_09.png


狙い通りの形式でデータが保存されています。

606_10.png

関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2015/03/29(日) 17:59:11|
  2. PHP
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<PHPのビルドインサーバーでCodeIgniterを動作させる | ホーム | AWS 課金発生時にアラートメールを送信する>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://symfoware.blog68.fc2.com/tb.php/1701-931a5c30
この記事にトラックバックする(FC2ブログユーザー)