-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding details about the changes to the PdoSessionHandler in 2.6 #4609
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,12 @@ | |
How to Use PdoSessionHandler to Store Sessions in the Database | ||
============================================================== | ||
|
||
.. caution:: | ||
|
||
There was a backwards-compatibility break in Symfony 2.6: the database | ||
schema changed slightly. See :ref:`Symfony 2.6 Changes <pdo-session-handle-26-changes>` | ||
for details. | ||
|
||
The default Symfony session storage writes the session information to | ||
file(s). Most medium to large websites use a database to store the session | ||
values instead of files, because databases are easier to use and scale in a | ||
|
@@ -24,18 +30,11 @@ configuration format of your choice): | |
# ... | ||
handler_id: session.handler.pdo | ||
|
||
parameters: | ||
pdo.db_options: | ||
db_table: session | ||
db_id_col: session_id | ||
db_data_col: session_data | ||
db_time_col: session_time | ||
db_lifetime_col: session_lifetime | ||
|
||
services: | ||
pdo: | ||
class: PDO | ||
arguments: | ||
# see below for how to use your existing DB config | ||
dsn: "mysql:dbname=mydatabase" | ||
user: myuser | ||
password: mypassword | ||
|
@@ -44,7 +43,7 @@ configuration format of your choice): | |
|
||
session.handler.pdo: | ||
class: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler | ||
arguments: ["@pdo", "%pdo.db_options%"] | ||
arguments: ["@pdo"] | ||
|
||
.. code-block:: xml | ||
|
||
|
@@ -53,16 +52,6 @@ configuration format of your choice): | |
<framework:session handler-id="session.handler.pdo" cookie-lifetime="3600" auto-start="true"/> | ||
</framework:config> | ||
|
||
<parameters> | ||
<parameter key="pdo.db_options" type="collection"> | ||
<parameter key="db_table">session</parameter> | ||
<parameter key="db_id_col">session_id</parameter> | ||
<parameter key="db_data_col">session_data</parameter> | ||
<parameter key="db_time_col">session_time</parameter> | ||
<parameter key="db_lifetime_col">session_lifetime</parameter> | ||
</parameter> | ||
</parameters> | ||
|
||
<services> | ||
<service id="pdo" class="PDO"> | ||
<argument>mysql:dbname=mydatabase</argument> | ||
|
@@ -76,7 +65,6 @@ configuration format of your choice): | |
|
||
<service id="session.handler.pdo" class="Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler"> | ||
<argument type="service" id="pdo" /> | ||
<argument>%pdo.db_options%</argument> | ||
</service> | ||
</services> | ||
|
||
|
@@ -94,14 +82,6 @@ configuration format of your choice): | |
), | ||
)); | ||
|
||
$container->setParameter('pdo.db_options', array( | ||
'db_table' => 'session', | ||
'db_id_col' => 'session_id', | ||
'db_data_col' => 'session_data', | ||
'db_time_col' => 'session_time', | ||
'db_lifetime_col' => 'session_lifetime', | ||
)); | ||
|
||
$pdoDefinition = new Definition('PDO', array( | ||
'mysql:dbname=mydatabase', | ||
'myuser', | ||
|
@@ -112,15 +92,74 @@ configuration format of your choice): | |
|
||
$storageDefinition = new Definition('Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler', array( | ||
new Reference('pdo'), | ||
'%pdo.db_options%', | ||
)); | ||
$container->setDefinition('session.handler.pdo', $storageDefinition); | ||
|
||
* ``db_table``: The name of the session table in your database | ||
* ``db_id_col``: The name of the id column in your session table (VARCHAR(128)) | ||
* ``db_data_col``: The name of the value column in your session table (BLOB) | ||
* ``db_time_col``: The name of the time column in your session table (INTEGER) | ||
* ``db_lifetime_col``: The name of the lifetime column in your session table (INTEGER) | ||
Configuring the Table and Column Names | ||
-------------------------------------- | ||
|
||
This will expect a ``sessions`` table with a number of different columns. | ||
The table name, and all of the column names, can be configured by passing | ||
a second array argument to ``PdoSessionHandler``: | ||
|
||
.. configuration-block:: | ||
|
||
.. code-block:: yaml | ||
|
||
# app/config/config.yml | ||
services: | ||
# ... | ||
session.handler.pdo: | ||
class: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler | ||
arguments: | ||
- "@pdo" | ||
- { 'db_table': 'sessions'} | ||
|
||
.. code-block:: xml | ||
|
||
<!-- app/config/config.xml --> | ||
<services> | ||
<service id="session.handler.pdo" | ||
class="Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler"> | ||
<argument type="service" id="pdo" /> | ||
<argument type="collection"> | ||
<argument key="db_table">sessions</argument> | ||
</argument> | ||
</service> | ||
</services> | ||
|
||
.. code-block:: php | ||
|
||
// app/config/config.php | ||
|
||
use Symfony\Component\DependencyInjection\Definition; | ||
// ... | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this empty line should be placed between the 2 comment line |
||
$storageDefinition = new Definition( | ||
'Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler', | ||
array( | ||
new Reference('pdo'), | ||
array('db_table' => 'session') | ||
) | ||
); | ||
$container->setDefinition('session.handler.pdo', $storageDefinition); | ||
|
||
.. versionadded:: 2.6 | ||
The ``db_lifetime_col`` was introduced in Symfony 2.6. Prior to 2.6, | ||
this column did not exist. | ||
|
||
The following things can be configured: | ||
|
||
* ``db_table``: (default ``session``) The name of the session table in your | ||
database; | ||
* ``db_id_col``: (default ``sess_id``) The name of the id column in your | ||
session table (VARCHAR(128)); | ||
* ``db_data_col``: (default ``sess_data``) The name of the value column in | ||
your session table (BLOB); | ||
* ``db_time_col``: (default ``sess_time``) The name of the time column in | ||
your session table (INTEGER); | ||
* ``db_lifetime_col``: (default ``sess_lifetime``) The name of the lifetime | ||
column in your session table (INTEGER). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't we move this block above the code? If I didn't want to change the default values, I would probably not be interested in how that would be done. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this block some become a definition list |
||
|
||
Sharing your Database Connection Information | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The default There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see that now. Is this what was causing the issue you and I talked about? Or just something you noticed when looking into it? But yes, we should have a note on this, and the locking strategy in general. Can you start a PR with that? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this was actually a misunderstanding on my part, see: symfony/symfony#13411 I think what that means is I can't use the One thing @Tobion mentioned is I should be using lazy connecting to the db: pass the connection params directly to the What do you think, want me to make a PR for that? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Boom, love it: A) Recommend that people use a separate PDO connection (and not to use that connection from in their app) Thanks - these will be good improvements! |
||
-------------------------------------------- | ||
|
@@ -163,6 +202,24 @@ of your project's data, you can use the connection settings from the | |
Example SQL Statements | ||
---------------------- | ||
|
||
.. _pdo-session-handle-26-changes: | ||
|
||
.. sidebar:: Schema Changes needed when Upgrading to Symfony 2.6 | ||
|
||
If you use the ``PdoSessionHandler`` prior to Symfony 2.6 and upgrade, you'll | ||
need to make a few changes to your session table: | ||
|
||
* A new session lifetime (``sess_lifetime`` by default) integer column | ||
needs to be added; | ||
* The data column (``sess_data`` by default) needs to be changed to a | ||
BLOG type. | ||
|
||
Check the SQL statements below for more details. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. couldn't we provide some kind of update sql script? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we could in theory, but it would take a bit of work (reading the config) + reading the DB engine. And it would be a little risky, since an upgrade script implies that it'll work (I could see people running it and expecting with 100% faith that it'll work, when maybe they've made some additional session changes). It's an unfortunate BC break, so I would like to make this change as obvious and easy as possible... but not too easy :) |
||
|
||
To keep the old (2.5 and earlier) functionality, change your class name | ||
to use ``LegacyPdoSessionHandler`` instead of ``PdoSessionHandler`` (the | ||
legacy class was added in Symfony 2.6.2). | ||
|
||
MySQL | ||
~~~~~ | ||
|
||
|
@@ -172,10 +229,10 @@ following (MySQL): | |
.. code-block:: sql | ||
|
||
CREATE TABLE `session` ( | ||
`session_id` VARBINARY(128) NOT NULL PRIMARY KEY, | ||
`session_data` BLOB NOT NULL, | ||
`session_time` INTEGER UNSIGNED NOT NULL, | ||
`session_lifetime` MEDIUMINT NOT NULL | ||
`sess_id` VARBINARY(128) NOT NULL PRIMARY KEY, | ||
`sess_data` BLOB NOT NULL, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just had an issue where I had to change to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👎 we should notice that huge sessions are bad by design. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It took me quite some time to find the cause of the auto-logout as there is no error. Good or bad design, it still should be noted imo. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about adding this small note?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this to specific to document? Anyway, I find the proposed text of @javiereguiluz way to long for something as minor and not that related as this. If we want to add something (I'm not sure yet), I would reduce it to just something as "If There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think something should be said about what happens if the data limit is exceeded: the session is reset without warning or error... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. .. note::
A ``BLOB`` column type can only store up to 64 kb. If the data stored in
a user's session exceeds this, the user will be logged out. Consider using
a ``MEDIUMBLOB`` if you need more space. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kbond if you're making a PR for the other change, maybe you can add this too? Thanks for your help on this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, I will make a PR. Instead of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This depends of the configuration of your database server actually. If you run MySQL in strict SQL compliance mode, it will return an error when saving the session instead of silently accepting the invalid value and dropping it |
||
`sess_time` INTEGER UNSIGNED NOT NULL, | ||
`sess_lifetime` MEDIUMINT NOT NULL | ||
) COLLATE utf8_bin, ENGINE = InnoDB; | ||
|
||
PostgreSQL | ||
|
@@ -186,10 +243,10 @@ For PostgreSQL, the statement should look like this: | |
.. code-block:: sql | ||
|
||
CREATE TABLE session ( | ||
session_id VARCHAR(128) NOT NULL PRIMARY KEY, | ||
session_data BYTEA NOT NULL, | ||
session_time INTEGER NOT NULL, | ||
session_lifetime INTEGER NOT NULL | ||
sess_id VARCHAR(128) NOT NULL PRIMARY KEY, | ||
sess_data BYTEA NOT NULL, | ||
sess_time INTEGER NOT NULL, | ||
sess_lifetime INTEGER NOT NULL | ||
); | ||
|
||
Microsoft SQL Server | ||
|
@@ -200,12 +257,12 @@ For MSSQL, the statement might look like the following: | |
.. code-block:: sql | ||
|
||
CREATE TABLE [dbo].[session]( | ||
[session_id] [nvarchar](255) NOT NULL, | ||
[session_data] [ntext] NOT NULL, | ||
[session_time] [int] NOT NULL, | ||
[session_lifetime] [int] NOT NULL, | ||
[sess_id] [nvarchar](255) NOT NULL, | ||
[sess_data] [ntext] NOT NULL, | ||
[sess_time] [int] NOT NULL, | ||
[sess_lifetime] [int] NOT NULL, | ||
PRIMARY KEY CLUSTERED( | ||
[session_id] ASC | ||
[sess_id] ASC | ||
) WITH ( | ||
PAD_INDEX = OFF, | ||
STATISTICS_NORECOMPUTE = OFF, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would prefer
- @pdo
instead of
- "@pdo"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using the
@
character in an unquoted string breaks the YAML syntax highlighting in the docs.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to be more precize, as the first character in an unquoted string (since that was a reserved character in Yaml 1.0)