【问题标题】:CakePHP: Use AWS's DynamoDB Session HandlerCakePHP:使用 AWS 的 DynamoDB 会话处理程序
【发布时间】:2014-01-12 05:11:54
【问题描述】:

我有一个托管在 AWS Elastic Beanstalk 上的 CakePHP 应用程序。由于将来我将使用多个 EC2 实例,我想将我的 PHP 会话存储在数据库中。 AWS 提供了一个非常好的库,用于在其 DynamoDB 数据库中存储 PHP 会话。见http://goo.gl/URoi3s

现在我将 AWS 开发工具包放在了我的供应商文件夹中,并为它创建了一个访问包装器(一个插件):

<?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() 已执行(经过测试),但会话并未存储到 DynamoDB 表中。当然,我之前创建了表,如果我在加载调度程序之前将对 AWS 库的调用直接添加到我的 webroot/index.php 中,一切正常。

我认为问题在于我的代码是在 CakePHP 调用 session_start() 之后执行的。那么实现它的最佳方法是什么? http://goo.gl/kUFUIR 对我没有帮助,我不想重写 AWS 库以兼容 CakePHP 接口。

【问题讨论】:

    标签: cakephp amazon-web-services amazon-dynamodb php


    【解决方案1】:

    那么实现它的最佳方法是什么? http://goo.gl/kUFUIR 对我没有帮助,我不想为beeing重写AWS库 兼容 CakePHP 接口。

    这实际上是最好的方法。这并不意味着重新发明轮子,OOP 中的抽象意味着您可以在通用接口中提供可以用其他东西替换的东西。您将外部 API 或代码包装在与您的系统兼容的 API 中,在本例中为 CakePHP 应用程序。

    将供应商库包装在实现 CakeSessionHandlerInterface 的 AwsSession 适配器中。这样一来,在您更改它的情况下,它的 API 与其他会话适配器兼容,甚至可能解决您的核心问题,因为 CakeSession 将负责初始化。

    您的组件在 CakePHP 中的会话之后被初始化,此时控制器已经被实例化,然后正在初始化它的所有组件。所以这发生在很晚的时候。您的替代方法是阻止 CakePHP 初始化会话,我从来不需要这样做,所以不自己查找就不知道了。挖掘 CakeSession。即使您设法这样做,其他组件(如默认 Auth 适配器)也依赖于能够使用 Sessions,因此您必须处理组件必须在 Auth 之前加载的问题。非常脆弱的系统,有很多可能的故障点。说真的,去 Session 适配器吧,猜猜它以这种方式工作不会那么痛苦。

    通过快速查看 DynamoDB 会话文档,这似乎很容易。扩展常规会话处理程序并仅重载它的初始化和垃圾收集以在其中添加 Aws API 调用,不能保证这是正确的,但似乎很容易。

    【讨论】:

      【解决方案2】:

      我在 CakePHP 3 中得到的结果。

      src/Network/Session/DynamoDbSession.php

      &lt?php 命名空间应用\网络\会话; 使用 Aws\DynamoDb\DynamoDbClient; 使用蛋糕\核心\配置; 类 DynamoDbSession 实现 \SessionHandlerInterface { 私人 $handler; /** * DynamoDbSession 构造函数。 */ 公共函数 __construct() { $client = new DynamoDbClient(Configure::read('DynamoDbCredentials')); $this->handler = $client->registerSessionHandler(array( 'table_name' => 配置::read('DynamoDbCredentials.session_table') )); } 公共函数关闭() { 返回 $this->handler->close(); } 公共函数销毁($session_id) { 返回 $this->handler->destroy($session_id); } 公共函数 gc($maxlifetime) { 返回 $this->handler->gc($maxlifetime); } 公共函数打开($save_path,$session_id) { 返回 $this->handler->open($save_path, $session_id); } 公共函数读取($session_id) { 返回 $this->handler->read($session_id); } 公共函数写入($session_id,$session_data) { 返回 $this->handler->write($session_id, $session_data); } }

      在 config/app.php 文件中激活它:

      '会话' => [ '默认值' => 'php', '处理程序' => [ '引擎' => 'DynamoDbSession' ], '超时' => (30 * 24 * 60) ]

      【讨论】:

        猜你喜欢
        • 2014-11-26
        • 1970-01-01
        • 2014-04-17
        • 2012-12-12
        • 1970-01-01
        • 2013-01-06
        • 1970-01-01
        • 1970-01-01
        • 2012-08-16
        相关资源
        最近更新 更多