所以,我试图在mysql数据库中存储会话。一切似乎都没问题,因为它会将数据写入会话表等。但是,我只是注意到我可以写出会话数据,尽管我的read方法是空的。因此,如果查看代码,最终的echo语句将写入“value” - 即使定义了零逻辑。有任何想法吗?谢谢!
class SessionManagement{
private $_hostname;
private $_username;
private $_password;
private $_database;
private $_timeout;
public function __construct() {
$CI =& get_instance();
$CI->load->database();
$this->_hostname = $CI->db->hostname;
$this->_username = $CI->db->username;
$this->_password = $CI->db->password;
$this->_database = $CI->db->database;
$this->_timeout = 60 * 60 * 10;
}
public function _open()
{
return TRUE;
}
public function _close()
{
return TRUE;
}
public function _read($id)
{
mysql_connect($this->_hostname, $this->_username, $this->_password);
mysql_select_db($this->_database);
$id = mysql_real_escape_string($id);
$sql = "SELECT session_data
FROM sessions
WHERE session_id = '$id'";
if ($result = mysql_query($sql)) {
if (mysql_num_rows($result)) {
$record = mysql_fetch_assoc($result);
return $record['session_data'];
}
}
return '';
}
public function _write($id, $data)
{
mysql_connect($this->_hostname, $this->_username, $this->_password);
mysql_select_db($this->_database);
$id = mysql_real_escape_string($id);
$data = mysql_real_escape_string(base64_encode(serialize(strip_tags($data))));
$access = time() + $this->_timeout;
$sql = "REPLACE INTO session (session_id, session_data, session_expires) VALUES('$id','$data', $access)";
return mysql_query($sql);
}
public function _gc($max)
{
return TRUE;
}
public function _destroy($id)
{
mysql_connect($this->_hostname, $this->_username, $this->_password);
mysql_select_db($this->_database);
$id = mysql_real_escape_string($id);
$sql = "DELETE
FROM session
WHERE session_id = '$id'";
return mysql_query($sql);
}
}
ini_set("session.save_handler", "user");
session_name("test");
session_set_cookie_params(0, '/', '.test.com');
$s = new SessionManagement();
session_set_save_handler(
array($s, '_open'),
array($s, '_close'),
array($s, '_read'),
array($s, '_write'),
array($s, '_destroy'),
array($s, '_gc')
);
session_start();
$_SESSION['test'] = "value";
ECHO $_SESSION['test'];
答案 0 :(得分:4)
您正在使用Codeigniter。它具有将会话存储到已构建的数据库中的功能。
只需删除不起作用的代码,然后使用Codeigniter的功能。您只需要配置它。
除此之外,如果你真的想“和你在一起”,你的代码就会出现多个问题。如果您遵循以下几点,很容易发现它们:
ini_set("session.save_handler", "user");
- 只要你不知道你做了什么,就不要这样做。在PHP中没有名为user
的预定义savehandler,也没有定义那个。基本上就是这样。所以我可以发现导致这种情况的两个真正的错误,其他步骤是必要的,这样你就可以处理未来的问题:
MY_SESSIONS
并从表SESSIONS
中读取,那么这将永远不会有效。您的代码中无法看到的其他潜在问题:
示例代码:
ob_start();
session_name("test");
session_set_cookie_params(0, '/', '.test.com');
$s = new SessionManagement();
$s->register();
session_start();
ECHO $_SESSION['test'], "\n"; # value
重构SessionManagement
类:
class SessionManagement
{
private $_timeout;
private $_db;
public function __construct() {
$CI =& get_instance();
$CI->load->database();
$this->_db = new LegacyMysqlDatabase(
$CI->db->hostname, $CI->db->username, $CI->db->password, $CI->db->database
);
$this->_timeout = 60 * 60 * 10;
}
public function _open() {
return TRUE;
}
public function _close() {
return TRUE;
}
public function _read($session_id) {
$db = $this->_db;
$session_id = $db->escape($session_id);
$sql = "SELECT session_data
FROM SESSION
WHERE session_id = '$session_id'";
if (!($result = $db->query($sql)) || !$result->getNumberOfRows()) {
return '';
}
$record = $result->fetchAssoc();
return $record['session_data'];
}
public function _write($session_id, $session_data) {
$db = $this->_db;
$session_id = $db->escape($session_id);
$session_data = $db->escape($session_data);
$session_expires = time() + $this->_timeout;
$sql = "REPLACE INTO SESSION (session_id, session_data, session_expires)
VALUES ('$session_id', '$session_data', $session_expires)";
return (bool)$db->query($sql); // cast to bool because PHP would cast to int
}
public function _gc($max) {
return TRUE;
}
public function _destroy($id) {
$db = $this->_db;
$session_id = $db->escape($id);
$sql = "DELETE
FROM SESSION
WHERE session_id = '$id'";
return $db->query($sql);
}
public function register() {
$registered = session_set_save_handler(
array($this, '_open'),
array($this, '_close'),
array($this, '_read'),
array($this, '_write'),
array($this, '_destroy'),
array($this, '_gc')
);
if (!$registered) {
throw new Exception('Can not register session savehandler.');
}
}
}
带错误处理的数据库交互代码:
class LegacyMysqlDatabase
{
private $_hostname;
private $_username;
private $_password;
private $_database;
private $_link;
private $_initError = false;
public function __construct($hostname, $username, $password, $database) {
$this->_hostname = $hostname;
$this->_username = $username;
$this->_password = $password;
$this->_database = $database;
}
public function query($sql) {
$link = $this->getLink();
$result = mysql_query($sql, $link);
if ($result === false) {
trigger_error(sprintf('Query "%s" failed: #%d: %s', $sql, mysql_errno($link), mysql_error($link)));
throw new Exception('Failed to query Mysql database.');
}
return new LegacyMysqlResult($result);
}
public function escape($string) {
return mysql_real_escape_string($string, $this->getLink());
}
private function getLink() {
if ($this->_initError) {
throw new Exception('Failed to initialize the database.');
}
if ($this->_link === null) {
$this->_initError = true;
$result = mysql_connect($this->_hostname, $this->_username, $this->_password);
if (!$result) {
throw new Exception('Can not connect to Mysql database.');
}
$this->_link = $result;
$selected = mysql_select_db($this->_database, $this->_link);
if (!$selected) {
trigger_error(sprintf('Can not select Mysql database "%s": #%d: %s', $this->_database, mysql_errno($result), mysql_error($result)));
throw new Exception(sprintf('Can not select Mysql database "%"', $this->_database));
}
$this->_initError = false;
}
return $this->_link;
}
}
class LegacyMysqlResult
{
private $_result;
public function __construct($result) {
$this->_result = $result;
}
public function getNumberOfRows() {
return mysql_num_rows($this->_result);
}
public function fetchAssoc() {
return mysql_fetch_assoc($this->_result);
}
}
答案 1 :(得分:1)
答案 2 :(得分:-1)
我不确定我理解你的问题。基本上你的脚本只有三行:
session_start();
$_SESSION['test'] = "value";
ECHO $_SESSION['test'];
会话管理的重点是,只要会话处于活动状态,您就不必在数据库中保存值(在大多数浏览器中,直到您关闭浏览器)。
你创建一个会话,php会向你的浏览器发送一个会话cookie,如果cookie被接受,只要会话处于活动状态,你就可以在任何页面上输出$ _SESSION ['test']。