2013-12-23 27 views
0

我有一個託管在AWS Elastic Beanstalk上的CakePHP應用程序。由於將來會使用多個EC2實例,我想將我的PHP會話存儲在數據庫中。 AWS提供了一個非常好的庫,用於在其DynamoDB數據庫中存儲PHP會話。見http://goo.gl/URoi3sCakePHP:使用AWS的DynamoDB會話處理程序

現在我的推杆AWS的SDK在我的文件夾的供應商,創造了一個訪問包裝它(插件):

<?php 

Configure::load('aws'); 

require_once VENDORS . 'autoload.php'; 
use Aws\Common\Aws; 

class AwsComponent extends Component 
{ 
    private $_aws; 

    public function __construct() 
    { 
     $this->_aws = Aws::factory(array(
      'key' => Configure::read('Aws.key'), 
      'secret' => Configure::read('Aws.secret'), 
      'region' => Configure::read('Aws.region') 
     )); 
    } 

    public function getClient($service) 
    { 
     return $this->_aws->get($service); 
    } 
} 

的包裝運作良好,我已經實現了一些東西S3。現在的會話處理程序添加以下代碼到我的AppController.php:

public $components = array('Aws.Aws'); 

public function beforeFilter() 
{ 
    $this->_setSessionStorage(); 
} 

private function _setSessionStorage() 
{ 
    $client = $this->Aws->getClient('dynamodb'); 

    $client->registerSessionHandler(array(
     'table_name' => 'sessions' 
    )); 
} 

的AWS的內部registerSessionHandler()被執行(測試過),但會議沒有beeing存儲到DynamoDB表。當然,我之前創建了表,如果在調度程序加載之前將調用直接添加到我的webroot/index.php,則一切正常。

我認爲問題在於我的代碼在CakePHP調用session_start()後執行。那麼實現它的最好方法是什麼? http://goo.gl/kUFUIR不能幫助我,我不想重寫AWS庫以便與CakePHP接口兼容。

回答

2

那麼實現它的最佳方法是什麼? http://goo.gl/kUFUIR 不幫助我,我不想重寫AWS庫以便與CakePHP接口兼容的 。

這實際上是最好的方法。這並不意味着重新發明輪子,OOP中的抽象意味着你可以在一個通用的接口中使用可替換的其他接口。您將外部API或代碼包裝在與系統兼容的API中,在本例中爲CakePHP應用程序。

將供應商庫包裝在實現CakeSessionHandlerInterface的AwsSession適配器中。這樣,在你改變它的情況下,它與其他會話適配器的API兼容,它甚至可以解決你的核心問題,因爲CakeSession將負責初始化。

您的組件在CakePHP中的會話之後初始化,當控制器已經實例化並且初始化其所有組件時。所以這發生在相當晚的時候。你的選擇是阻止CakePHP初始化會話,我從來沒有必要這樣做,所以不知道沒有自己查看它。在CakeSession中挖掘。即使您設法這麼做,其他組件也會像默認的Auth適配器一樣依賴於能夠使用Sessions,因此您必須考慮組件必須在Auth之前加載的問題。相當脆弱的系統,有許多可能的故障點。認真地說,去適應Session適配器,猜測它讓這種方式工作起來不那麼痛苦。

通過快速瀏覽DynamoDB Session文檔,這看起來很容易。擴展常規會話處理程序並僅重載它的init和garbage collection以在其中添加Aws API調用,但不保證這是正確的,但似乎很容易。

+0

好,謝謝,如果是我會試試看的唯一途徑。 – iscon

1

我結束了在CakePHP的3

的src /網絡/會話/ DynamoDbSession什麼。PHP

 
<?php 

namespace App\Network\Session; 

use Aws\DynamoDb\DynamoDbClient; 
use Cake\Core\Configure; 

class DynamoDbSession implements \SessionHandlerInterface 
{ 

    private $handler; 

    /** 
    * DynamoDbSession constructor. 
    */ 
    public function __construct() 
    { 
     $client = new DynamoDbClient(Configure::read('DynamoDbCredentials')); 

     $this->handler = $client->registerSessionHandler(array(
      'table_name' => Configure::read('DynamoDbCredentials.session_table') 
     )); 
    } 

    public function close() 
    { 
     return $this->handler->close(); 
    } 

    public function destroy($session_id) 
    { 
     return $this->handler->destroy($session_id); 
    } 

    public function gc($maxlifetime) 
    { 
     return $this->handler->gc($maxlifetime); 
    } 

    public function open($save_path, $session_id) 
    { 
     return $this->handler->open($save_path, $session_id); 
    } 

    public function read($session_id) 
    { 
     return $this->handler->read($session_id); 
    } 

    public function write($session_id, $session_data) 
    { 
     return $this->handler->write($session_id, $session_data); 
    } 

} 

激活它在配置/ app.php文件:

 
'Session' => [ 
     'defaults' => 'php', 
     'handler' => [ 
      'engine' => 'DynamoDbSession' 
     ], 
     'timeout' => (30 * 24 * 60) 
]