发布于 2015-12-06 07:32:43 | 202 次阅读 | 评论: 0 | 来源: 网络整理
在 Symfony 2.6 中有一个后向兼容:数据库模式稍作改变。更多细节请见 Symfony 2.6 的改变。
默认的 Symfony 的 session 存储将 session 信息写进文件。大多数的中到大型的网页使用一个数据库储存 session 的值而不是文件,因为数据库很好用并且适应多线程网页服务器环境。
Symfony 有一个内建的数据库 session 的存储解决方案名为 PdoSessionHandler。使用这个,你只需要在主配置文件中改变一些参数:
YAML:
# app/config/config.yml
framework:
session:
# ...
handler_id: session.handler.pdo
services:
session.handler.pdo:
class: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
public: false
arguments:
- "mysql:dbname=mydatabase"
- { db_username: myuser, db_password: mypassword }
XML:
<!-- app/config/config.xml -->
<framework:config>
<framework:session handler-id="session.handler.pdo" cookie-lifetime="3600" auto-start="true"/>
</framework:config>
<services>
<service id="session.handler.pdo" class="Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler" public="false">
<argument>mysql:dbname=mydatabase</agruement>
<argument type="collection">
<argument key="db_username">myuser</argument>
<argument key="db_password">mypassword</argument>
</argument>
</service>
</services>
PHP:
// app/config/config.php
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
$container->loadFromExtension('framework', array(
...,
'session' => array(
// ...,
'handler_id' => 'session.handler.pdo',
),
));
$storageDefinition = new Definition('Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler', array(
'mysql:dbname=mydatabase',
array('db_username' => 'myuser', 'db_password' => 'mypassword')
));
$container->setDefinition('session.handler.pdo', $storageDefinition);
这将会产生一个有着很多不同列的 sessions 表。表的名称以及所有的列名称,可以通过向 PdoSessionHandler 传递一个第二数组参数的方式设置:
YAML:
# app/config/config.yml
services:
# ...
session.handler.pdo:
class: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
public: false
arguments:
- "mysql:dbname=mydatabase"
- { db_table: sessions, db_username: myuser, db_password: mypassword }
XML:
<!-- app/config/config.xml -->
<services>
<service id="session.handler.pdo" class="Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler" public="false">
<argument>mysql:dbname=mydatabase</agruement>
<argument type="collection">
<argument key="db_table">sessions</argument>
<argument key="db_username">myuser</argument>
<argument key="db_password">mypassword</argument>
</argument>
</service>
</services>
PHP:
// app/config/config.php
use Symfony\Component\DependencyInjection\Definition;
// ...
$storageDefinition = new Definition('Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler', array(
'mysql:dbname=mydatabase',
array('db_table' => 'sessions', 'db_username' => 'myuser', 'db_password' => 'mypassword')
));
$container->setDefinition('session.handler.pdo', $storageDefinition);
db_lifetime_col 是在 Symfony 2.6 中被引进的。2.6 之前的版本并不存在。
下列这些参数你必须设置:
db_table (默认为 sessions):
你的数据库中的 session 表的名称;
db_id_col (默认为 sess_id):
你的 session 表的 id 列的名称(文本类型(128));
db_data_col (默认为 sess_data):
你的 session 表的 value 列的名称 (二进制大对象);
db_time_col (默认为 sess_time): 你的 session 表的 time 列的名称(整型);
db_lifetime_col (默认为 sess_lifetime): T你的 session 表的 lifetime 列的名称(整型).
根据给定的设置,数据库的连接只是为了 session 存储连接而设置的。当你为 session 数据使用分离的数据库时这个是可以的。
但是如果你想要将 session 数据像你的工程的其它的数据一样储存在同一个数据库中,你可以使用通过引用数据库的 parameters.yml 文件的连接设置——相关的参数在如下定义:
YAML:
services:
session.handler.pdo:
class: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
public: false
arguments:
- "mysql:host=%database_host%;port=%database_port%;dbname=%database_name%"
- { db_username: %database_user%, db_password: %database_password% }
XML:
<service id="session.handler.pdo" class="Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler" public="false">
<argument>mysql:host=%database_host%;port=%database_port%;dbname=%database_name%</agruement>
<argument type="collection">
<argument key="db_username">%database_user%</argument>
<argument key="db_password">%database_password%</argument>
</argument>
</service>
PHP:
$storageDefinition = new Definition('Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler', array(
'mysql:host=%database_host%;port=%database_port%;dbname=%database_name%',
array('db_username' => '%database_user%', 'db_password' => '%database_password%')
));
如果你使用 PdoSessionHandler 是 Symfony 2.6 之前的版本然后进行了升级,你的 session 表需要做出一些改变:
- 需要添加新的 session lifetime (sess_lifetime 默认)整型列;
- data 列(sess_data 默认)需要改成二进制大对象型。
更多细节详见下面的 SQL 语句。
为了保存以前(2.5 以及更早的)版本的功能,将你的类的名称由 PdoSessionHandler 改成 LegacyPdoSessionHandler(Symfony 2.6.2 中添加的旧的类)。
创建新的数据库的表的 SQL 语句如下所示(MySQL):
CREATE TABLE `sessions` (
`sess_id` VARBINARY(128) NOT NULL PRIMARY KEY,
`sess_data` BLOB NOT NULL,
`sess_time` INTEGER UNSIGNED NOT NULL,
`sess_lifetime` MEDIUMINT NOT NULL
) COLLATE utf8_bin, ENGINE = InnoDB;
二进制大对象类型的栏目只能储存到 64 kb。如果存储的用户的 session 数据超过这个值,可能就会出现异常或者它们的 session 会被重置。如果你需要更多的存储空间可以考虑使用 MEDIUMBLOB。
对于 PostgreSQL,代码如下所示:
CREATE TABLE sessions (
sess_id VARCHAR(128) NOT NULL PRIMARY KEY,
sess_data BYTEA NOT NULL,
sess_time INTEGER NOT NULL,
sess_lifetime INTEGER NOT NULL
);
对于微软的 SQL Server,代码如下所示:
CREATE TABLE [dbo].[sessions](
[sess_id] [nvarchar](255) NOT NULL,
[sess_data] [ntext] NOT NULL,
[sess_time] [int] NOT NULL,
[sess_lifetime] [int] NOT NULL,
PRIMARY KEY CLUSTERED(
[sess_id] ASC
) WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]