我正在开发一个电子商务网站,我需要在其中存储数据库中的会话。我通过实现由php本身提供的 SessionHandlerInterface 类来实现这一点。但是它完全正常并且做了在数据库中存储会话,并正确读取它们。
然而,当我使用unset来取消设置会话变量时,我遇到了问题。有时它确实有效。有时它不会。
For example:
如果我有一个名为ABC
unset
的会话变量,可能会将其从数据库中删除,或者不会删除该变量。
<?php
//inc.session.php
require_once 'RemoteAddress.php';
class SysSession implements SessionHandlerInterface
{
private $remote_write;
private $remote_read;
private $link;
private $ip_address_write;
private $ip_address_read;
public function open($savePath, $sessionName)
{
$link = new mysqli("localhost","root","","cakenbake");
if($link){
$this->link = $link;
return true;
}else{
return false;
}
}
public function close()
{
mysqli_close($this->link);
return true;
}
public function read($id)
{
$this->remote_read=new RemoteAddress();
$this->ip_address_read=$this->remote_read->getIpAddress();
$stmt=$this->link->prepare("SELECT `Session_Data`,`ip_address` FROM Session WHERE `Session_Id` = ? AND `Session_Expires` > '".date('Y-m-d H:i:s')."'");
$stmt->bind_param("s",$id);
$stmt->execute();
//$result = mysqli_query($this->link,"SELECT Session_Data FROM Session WHERE Session_Id = '".$id."' AND Session_Expires > '".date('Y-m-d H:i:s')."'");
/*$result=$this->link->prepare("Some query inside")
* This shows up an error stating prepare method not found
*
*/
$res=$stmt->get_result();
if($row=$res->fetch_assoc()){
if($this->ip_address_read==$row['ip_address'])
return $row['Session_Data'];
else return "";
}else{
return "";
}
}
public function write($id, $data)
{
$this->remote_write=new RemoteAddress();
$this->ip_address_write=$this->remote_write->getIpAddress();
if(!empty($data))
{
$DateTime = date('Y-m-d H:i:s');
$NewDateTime = date('Y-m-d H:i:s',strtotime($DateTime.' + 1 hour'));
$stmt=$this->link->prepare("REPLACE INTO Session SET Session_Id = ?, Session_Expires = '".$NewDateTime."', Session_Data = '".$data."', ip_address = '".$this->ip_address_write."'");
$stmt->bind_param("s",$id);
// $result = mysqli_query($this->link,"REPLACE INTO Session SET Session_Id = '".$id."', Session_Expires = '".$NewDateTime."', Session_Data = '".$data."'");
if($stmt->execute()){
return true;
}else{
return false;
}
}
}
public function destroy($id)
{
$stmt = $this->link->prepare("DELETE FROM Session WHERE Session_Id =?");
$stmt->bind_param("s",$id);
if($stmt->execute()){
return true;
}else{
return false;
}
}
public function gc($maxlifetime)
{
$result = $this->link->query("DELETE FROM Session WHERE ((UNIX_TIMESTAMP(Session_Expires) + ".$maxlifetime.") < UNIX_TIMESTAMP(NOW()))");
if($result){
return true;
}else{
return false;
}
}
}
$handler = new SysSession();
session_set_save_handler($handler, true);
?>
以上代码存储和读取数据库中的会话。
Structure of the session table.
这可能是造成这种奇怪行为的可能原因。我是否还必须实现unset
功能?
我该如何解决这个问题?
如果您可以建议我另外编写一些用于存储在数据库中的代码。这也可以,但我不需要任何框架,例如codeigniter
和Yii2
。
如果您需要有关此问题的更多信息,我会更新我的问题。
提前致谢!
答案 0 :(得分:0)
问题不在于unset
函数,而在于write
函数。write
函数负责对特定会话ID进行的任何更新。
奇怪的事实并非与未设置的一致,而是与你实施的写作功能有关。
请参阅!empty
约束检查您的数据是否为空。我可以猜到,在删除特定变量后,该特定id的数据库必须为空。所以写入尝试更新你的行有一个空值,但有了这个约束,它就无法这样做。
只需删除!empty
标记,它就像魅力一样。