我有一个非常具体的问题,关于使用mysql数据库的自定义会话处理程序。我浏览了其他主题,因为这里有一些涉及自定义会话处理程序的主题,但没有人回答我的问题。 我使用自定义会话处理程序在一个名为“会话”类:自定义数据库会话处理程序 - 特定读取问题
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;
}
}
}
这是一个很好的命名约定,让你的类名为'Uppercased'和函数名'camelCased()',它有助于提高可读性。 –