Session代理样例

3.4 版本
维护中的版本

session代理机制有多种用途,本章介绍两个常见用法。并不是使用常规的Session操作,而是你可以通过定义一个类让这个类去继承SessionHandlerProxy类,来创建一个自定义的保存操作。

然后,定义一个新的服务去关联这个自定义的session操作:

1
2
3
4
# app/config/services.yml
services:
    app.session_handler:
        class: AppBundle\Session\CustomSessionHandler
1
2
3
4
5
6
7
8
9
10
11
<!-- app/config/services.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">
 
    <services>
        <service id="app.session_handler" class="AppBundle\Session\CustomSessionHandler" />
    </services>
</container>
1
2
// app/config/config.php
$container->register('app.session_handler', 'AppBundle\Session\CustomSessionHandler');

最后,使用framework.session.handler_id配置选项去告诉symfony去使用你自己的session操作替代默认的那个:

1
2
3
4
5
# app/config/config.yml
framework:
    session:
        # ...
        handler_id: app.session_handler
1
2
3
4
5
6
7
8
9
10
<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">
    <framework:config>
        <framework:session handler-id="app.session_handler" />
    </framework:config>
</container>
1
2
3
4
5
6
7
8
// app/config/config.php
$container->loadFromExtension('framework', array(
    // ...
    'session' => array(
        // ...
        'handler_id' => 'app.session_handler',
    ),
));

请继续阅读下文,学习如何在实践中运用session操作来解决两个常见的用例:加密Session信息和定义只读型访客Sessions。

加密Session信息 

如果您想对Session数据进行加密,可以使用代理来根据需要,对Session进行加密和解密:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// src/AppBundle/Session/EncryptedSessionProxy.php
namespace AppBundle\Session;
 
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
 
class EncryptedSessionProxy extends SessionHandlerProxy
{
    private $key;
 
    public function __construct(\SessionHandlerInterface $handler, $key)
    {
        $this->key = $key;
 
        parent::__construct($handler);
    }
 
    public function read($id)
    {
        $data = parent::read($id);
 
        return mcrypt_decrypt(\MCRYPT_3DES, $this->key, $data);
    }
 
    public function write($id, $data)
    {
        $data = mcrypt_encrypt(\MCRYPT_3DES, $this->key, $data);
 
        return parent::write($id, $data);
    }
}

只读型访客Sessions 

有一些程序,对于访客用户(未登陆)也需要session。但此种情形,没有特殊必要来写入这个session。在这种情况下,你可以在它被写之前拦截Session:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// src/AppBundle/Session/ReadOnlySessionProxy.php
namespace AppBundle\Session;
 
use AppBundle\Entity\User;
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
 
class ReadOnlySessionProxy extends SessionHandlerProxy
{
    private $user;
 
    public function __construct(\SessionHandlerInterface $handler, User $user)
    {
        $this->user = $user;
 
        parent::__construct($handler);
    }
 
    public function write($id, $data)
    {
        if ($this->user->isGuest()) {
            return;
        }
 
        return parent::write($id, $data);
    }
}

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)