自定义数据库会话处理程序 - 特定读取问

时间:2012-11-06 19:49:44

标签: php mysql session handler

我对使用mysql数据库的自定义会话处理程序有一个非常具体的问题。我查看了其他主题,因为这里有一些涉及自定义会话处理程序的主题,但没有人回答我的问题。 我在名为“sessions”的类中使用自定义会话处理程序:

require_once "mySQL.php";

class sessions {
private $db;
public function __construct(){
    $this->db=new mySQL('localhost', user, pw, database);
    session_set_save_handler(array(&$this,"open"),
                     array(&$this,"close"),
                     array(&$this,"read"),
                     array(&$this,"write"),
                     array(&$this,"destroy"),
                     array(&$this,"gc"));
    register_shutdown_function('session_write_close');
    session_start();
} 
public function read($sessionID){
    $abfrage="SELECT * FROM sessions WHERE id='".$sessionID."'";
    $result= $this->db->query($abfrage);
    if ($result == false){
        return '';
    }
    if (count($result) > 0){
        return $result[0]["value"];
    }
    else{ 
    return '';
    }
}

在“mySQL.php”中只编写了一个“mySQL”类,它创建了一个与数据库的mysqli连接。这是有效的,而不是问题。我想把重点放在“阅读”例程上,因为这似乎是主要问题。如果我现在通过

创建会话
require_once "classes/sessions.php";
$SESSION=new sessions();
$token=hash("sha256",session_id().time());
$_SESSION['token']=$token;
$_SESSION['running']=1

并将值写入会话中,创建正确的数据库值:

id (varchar 64) = 54ul84nhc3aimqc55efcs49js4
lastUpdated (int 11) = 1352226239
start (int 11) = 1352226233
value (varchar 20000) =     token|s:64:"2b92aa848a86741ef11d800c3dce527fdcee264f50de10381941241c3d9cc9ee";running|i:1;

甚至垃圾收集器工作正常,但当我重新加载页面并尝试回应

$_SESSION['running']

我收到错误“通知:未定义的索引:正在运行”。调试器运行通知上面发布的读取例程返回1(它将等于布尔值“true”?!)而不是值。我检查了那个案例的读取例程中的“sessionID”是会话表中的那个,所以我基本上丢了。如果你可以帮助我,那将是非常好的,因为到目前为止,我已经对这种自定义会话处理程序提供的可能性印象深刻。

也许在这里提出一个附带问题也许是可能的。当我重新加载页面时会话的构造函数被“$ SESSION = new sessions();”调用是正确的。即使已经有会话在运行(但是这种行为不会改变session_id)?或者这是由于我的会话读取程序被破坏了吗?

感谢您的帮助。

编辑:我在xampp发行版中使用PHP / 5.4.4和MySQL 5.5.25a以及phpmyAdmin 3.5.2来设置数据库。会话表是一个格式为“MEMORY”的表,这就是我使用varchar 20000字段而不是文本字段的原因。我刚刚看到这篇文章Why does mysql_query() return TRUE with a SELECT statement? 声明当服务器突然中断连接时,mysql_query会不时返回true。但是,我无法弄清楚这可能是什么原因。 我现在正在添加mySQL类,也许这个问题涉及错误:

<?php
class mySQL
{
public $mySQLiObj;
public $lastSQLQuery;
public $lastSQLStatus;
public $lastInsertID;
public function __construct($server,$user,$password,$db,$port="3306"){
    //erstelle db-objekt
    $this->mySQLiObj= new mysqli($server,$user,$password,$db,$port);
    if (mysqli_connect_errno()){
        echo "Keine Verbindung zum MySQL-Server möglich.";
        trigger_error("MYSQL-Connection-Error",E_USER_ERROR);           
        die();
    }
    //Zeichensatz auf utf8 setzen
    $this->query("SET NAMES utf8");
}
public function __destruct(){
    $this->mySQLiObj->close();
}
public function query($sqlQuery,$resultset=false){
    $this->lastSQLQuery=$sqlQuery;
    $result=$this->mySQLiObj->query($sqlQuery);
    if($resultset == true){
        if($result == false) {
            $this->lastSQLStatus=false;
        }
        else
        {
            $this->lastSQLStatus = true;
        }
        return $result;
    }
    if($resultset == false) {
        $return = $this->makeArrayResult($result);
        return $return;
    }
}
private function makeArrayResult($ResultObj){
    if ($ResultObj==false){
        //Fehler aufgetreten
        $this->lastSQLStatus=false;
        return false;
    }
    else if ($ResultObj == true) {
        //UPDATE,INSERT etc. statement es wird nur true zurückgegeben
        $this->lastSQLStatus = true;
        $this->lastInsertID = $this->mySQLiObj->insert_id;
        return true;
    }
    else if ($ResultObj->num_rows == 0){
        //Kein Ergebnis bei SELECT,SHOW,DESCRIBE oder EXPLAIN Statement
        $this->lastSQLStatus = true;
        return array();
    }
    else {
        $array = array();
        while($line = $ResultObj->fetch_array(MYSQLI_ASSOC)){
            array_push($array,$line);
        }
        $this->lastSQLStatus=true;
        return $array;
    }
}

}

1 个答案:

答案 0 :(得分:0)

所以经过大量的尝试和错误,回头看看我得到会话处理程序的基本布局的书,我自己回答了这个问题。 看起来像这样

$SESSION=new sessions();

是关键点。不是通过显式调用创建会话,而是必须调用

session_set_save_handler(new sessions);

并删除sessions类中构造函数的行。然而有趣的是,由此产生了这种奇怪的错误。

感谢您一看,也许这对某人有帮助。