PHP数据库会话为同一会话ID创建多个记录


PHP database sessions creating multiple records for same session ID

所以我遇到了一个奇怪的问题,PHP会话多次保存到数据库(MongoDB)中,都使用相同的ID。第一条记录有正确的会话数据,而第二条记录有错误的会话数据。这导致我的会话在下一页(或下一个AJAX调用)上立即失败,因为它正在获取最新记录。

这是我的会话ini设置:

array(
'session.auto_start' => '0',
'session.bug_compat_42' => '',
'session.bug_compat_warn' => '',
'session.cache_expire' => '180',
'session.cache_limiter' => 'must-revalidate',
'session.cookie_domain' => '',
'session.cookie_httponly' => '1',
'session.cookie_lifetime' => '0',
'session.cookie_path' => '/',
'session.cookie_secure' => '1',
'session.entropy_file' => '',
'session.entropy_length' => '0',
'session.gc_divisor' => '1000',
'session.gc_maxlifetime' => '14400',
'session.gc_probability' => '1',
'session.hash_bits_per_character' => '5',
'session.hash_function' => '0',
'session.name' => 'Game',
'session.referer_check' => '',
'session.save_handler' => 'user',
'session.save_path' => '/var/lib/php/session',
'session.serialize_handler' => 'php',
'session.use_cookies' => '1',
'session.use_only_cookies' => '1',
'session.use_trans_sid' => '0'
)

我的CakePHP设置:

Configure::write('Session', array(
'cookie' => PROJECT,
'checkAgent' => false,
'autoRegenerate' => false, // We don't want it to regenerate
'defaults' => 'database',
'handler' => array(
    'engine' => 'DatabaseSession',
    'model' => 'Session'
),
'ini' => array(
    'session.cookie_lifetime' => 0, // Until the browser is closed
    'session.cookie_httponly' => true,
    'session.referer_check' => '',
    'session.cache_limiter' => 'nocache'
),
));

以下是数据库中多条记录的示例(请注意,它们具有相同的ID,但内容不同):

{ "_id" : ObjectId("5011b8c9564d444d04000083"), "id" : "mnor9aspiacp3g41qq8g0fotk2", "data" : "Config|a:3:{s:9:'"userAgent'";s:0:'"'";s:4:'"time'";i:1343353096;s:9:'"countdown'";i:10;}fb_466806330012492_code|s:74:'"2.AQC3yKQXi2e-6_VjI.3600.1343343600.1-672639577|pkfXkSypomU_3RY2-xM3A93rGrVo'";fb_4668063X30012492_access_token|s:110:'"AAAGojtF6Xs0wBAIoUwOoMU3WIt4ZBAih0NUvwtGePBxYv6oOT1QvbEZAb77j2h8ZBXKnpHrXktxHmz1WXCyr5VR9RwdaiGzrxfNRgEPr06gAZDZD'";fb_466806330012492_user_id|s:9:'"xxxx'";Game|a:6:{s:7:'"user_id'";s:24:'"4ff60631ec0f92c5690002a6'";s:9:'"player_id'";s:24:'"4ff60631ec0f92c5690002a7'";s:7:'"game_id'";s:24:'"5009ce57d09b3efe03000000'";s:11:'"facebook_id'";s:9:'"xxx'";s:11:'"accessToken'";s:110:'"AAAGoXjtF6s0wBAIoUwOoMXU3WIt4ZBAih0NUvwXtGePBxYv6oOT1QvbEZAb77j2h8ZBKnpHrXktxHmz1WCyr5VR9RwdaiGzrxfNRgEXPr06gAZDZD'";s:5:'"round'";i:1;}", "expires" : NumberLong(1343338697), "modified" : ISODate("2012-07-26T21:38:17.083Z"), "created" : ISODate("2012-07-26T21:38:17.083Z") }
{ "_id" : ObjectId("5011b8ca564d445c0400008f"), "id" : "mnor9aspiacp3g41qq8g0fotk2", "data" : "Config|a:3:{s:9:'"userAgent'";s:0:'"'";s:4:'"time'";i:1343353098;s:9:'"countdown'";i:10;}", "expires" : NumberLong(1343338698), "modified" : ISODate("2012-07-26T21:38:18.689Z"), "created" : ISODate("2012-07-26T21:38:18.689Z") }

我似乎想不通这个问题。我试着切换到内存缓存存储,但同样的事情也发生了。还有几点需要注意:

  • 该网站正在使用HTTPS
  • 我正在使用添加到会话中的Facebook API,但我首先创建应用程序会话
  • 会话ID为的cookie确实存在,并且正在每个请求的所有标头中传递
  • 我在亚马逊EC2上运行

由于我的ini设置看起来是正确的,我已经没有什么想法了,我已经在整个应用程序中放置了调试语句,以确保操作顺序是正确的。到目前为止一切都很好。

在mongodb端,您可以使用ensureIndex({id:1},{unique:true})来防止插入发生。