我有一个使用YII的网站。它所做的一件事是将会话信息存储到MySql数据库表YiiSession中。同样在一个单独的表(users_sessions)中,插入一个包含以下信息的新行:
- 会话id <
- 用户id/gh>
- 用户在线状态
我只在用户登录期间对users_session进行插入。
但是我不明白,当用户注销时,与该用户关联的会话被删除了。
请注意,users_session中的session_id是YiiSession中session_id的外键。但是在YiiSession中的那个仍然存在,即使它有一个截止日期。
什么机制可能删除行?请帮助。
您应该扩展CDbHttpSession
并覆盖destroySession($id)
方法。在这里,您可以添加代码并删除您的条目。
在config/main.php中配置Yii使用您的会话类而不是它自己的会话类:
'session' => array(
'autoStart' => true,
'class' => 'application.components.<your session class name>',
'connectionID' => 'db',
'sessionTableName' => 'session',
'autoCreateSessionTable' => false,
'timeout' => 3600, // 60 min
),
但是,我不会在单独的表中这样做,只是在YiiSession表中添加一些字段。我就是这么做的,而且效果很好。
编辑: 您应该在protected/components
中创建一个名为MyDbHttpSession.php
的文件。在这个文件中,像这样扩展CDbHttpSession:
class MyDbHttpSession extends CDbHttpSession
{
protected function createSessionTable($db, $tableName)
{
// basically this is a copy of CDbHttpSession
$db->createCommand()->createTable($tableName, array(
'id' => 'CHAR(32) PRIMARY KEY',
'expire' => 'integer',
'data' => $blob,
// your additional fields
'idUser' => 'INT(10) NULL',
'online' => 'TINYINT(1)',
// more of your fields here if you have
));
}
// this sets the user ID by session ID
public function setIdUser($idUser)
{
$db = $this->getDbConnection();
$db->setActive(true);
$db->createCommand()->update($this->sessionTableName, array('idUser' => (int) $idUser),
'id=:id', array(':id' => $this->sessionId)
);
}
// and this sets the online status, pass true or false to $online
public function setOnline($online)
{
$db = $this->getDbConnection();
$db->setActive(true);
$db->createCommand()->update($this->sessionTableName, array('online' => (int) $online),
'id=:id', array(':id' => $this->sessionId)
);
}
}
设置Yii使用你的会话类,而不是像我上面写的那样使用它自己的会话类。
您应该已经有一个类WebUser
。如果没有,在protected/components
中创建一个,并扩展CWebUser
。在这个类中添加一个方法afterLogin
:
public function afterLogin($fromCookie)
{
// store user ID and online status in session table
Yii::app()->session->setIdUser($this->id);
Yii::app()->session->setOnline(true);
return parent::afterLogin($fromCookie);
}
你可以在Yii的任何地方使用Yii::app()->session->setOnline(true);
或Yii::app()->session->setOnline(false);