2009-06-24 83 views
3

好的,我很困惑。我有一个存储在会话中的对象。我可以添加项目到这个对象。到目前为止很简单。我初始化这样的对象:PHP会话混乱

$template = new Template($mysqli); 
$_SESSION['template'] = serialize($template); 

现在,这个应该创建一个崭新的品牌对象,并将其分配给会话。然后我有一些代码通过AJAX请求添加项目。该代码如下:

$template = unserialize($_SESSION['template']); 
$prodid = $_GET['product_id']; 
$template->addItem($prodid); 
echo var_dump($template->getItems()); 
$_SESSION['template'] = serialize($template); 

再次,应该很简单。现在是这个问题,第一个代码不应该重置$_SESSION['template'],所以我得到了迄今为​​止添加的所有项目,重新加载页面并不能解决问题。

我发现了导致恶作剧的文件,但我不知道我能做些什么。这是一个包含,它是网站不同部分的功能所必需的。我正在为网站添加功能,如果我删除了功能,我不认为所有者会这么做。这里的文件:

<?php 

include_once('DBE.class.php') ; 

################################################ 
# Function: Sessions_open 
# Parameters: $path (string), $name (string) 
# Returns: bool 
# Description: This is an over-ride function call 
#  that we need to create so that the php internal 
#  session manager doesn't store our session in the 
#  file system, since we are storing it in the 
#  db. Storing a session in a file system on the 
#  server inhibits scalability for two reasons: 
#  1: A large number of users may be hitting the site 
#   and clog the space on the hard-drive of the server 
#   due to the sheer amount of session files stored 
#  2: The website may be behind a load-balancer and 
#   therefore the server handling the page request 
#   may not have the session stored on its file system 
################################################ 
function Sessions_open ($path, $name) { 
    return TRUE ; 
} 


################################################ 
# Function: Sessions_close 
# Parameters: N/A 
# Returns: bool 
# Description: This is an over-ride function call 
#  that we need to create so that the php internal 
#  session manager doesn't store our session in the 
#  file system, since we are storing it in the 
#  db. Storing a session in a file system on the 
#  server inhibits scalability for two reasons: 
#  1: A large number of users may be hitting the site 
#   and clog the space on the hard-drive of the server 
#   due to the sheer amount of session files stored 
#  2: The website may be behind a load-balancer and 
#   therefore the server handling the page request 
#   may not have the session stored on its file system 
################################################ 
function Sessions_close() { 
    return TRUE ; 
} 


################################################ 
# Function: Sessions_read 
# Parameters: $SessionID (string) 
# Returns: (string) or (false) on error 
# Description: This function is used at startup to read 
#   the contents of the session. 
#   If no sess data, the empty string ("") is returned. 
#   Otherwise, the serialized sess data is returned. 
#   On error, false is returned. 
################################################ 
function Sessions_read ($SessionID) { 

    include_once('DBE.class.php') ; 
    $dbe = new DBE() ; 

    //default return value to false 
    $returnVal = FALSE ; 

    $query = "SELECT DataValue 
         FROM Sessions 
         WHERE SessionID = '$SessionID' " ; 

    $result = $dbe->Select($query) ; 

    if(count($result) == 1) { 
     $returnVal = $result[0]['DataValue'] ; 

     //update the session so that we don't time-out after creating 
     $query = "UPDATE Sessions 
          SET LastUpdated = NOW() 
          WHERE SessionID = '$SessionID'" ; 
     $dbe->Update($query) ; 

    } else { 
     //Insert here to simplify the write function 
     $query = "INSERT INTO Sessions (SessionID, DataValue) VALUES ('$SessionID', '')" ; 

     $dbe->Insert($query) ;   //pass the insert stmt 

     //set returnVal to '' being that we didn't find the SessionID 
     $returnVal = '' ; 
    } 

    return($returnVal) ; 
} 

################################################ 
# Function: Sessions_write 
# Parameters: $SessionID (string), $Data 
# Returns: bool 
# Description: This function is used at startup to read 
#   the contents of the session. 
#   If no sess data, the empty string ("") is returned. 
#   Otherwise, the serialized sess data is returned. 
#   On error, false is returned. 
################################################ 
function Sessions_write($SessionID, $Data) { 

    include_once('DBE.class.php') ; 
    $dbe = new DBE() ; 

    //default to true 
    $returnVal = TRUE ; 

    //update the session 
    $query = "UPDATE Sessions 
          SET DataValue = '$Data' 
         WHERE SessionID = '$SessionID'" ; 

    $result = $dbe->Update($query) ; //pass the update stmt to the dbEngine.. 

    //test for success 
    if($result == -1) 
     $returnVal = FALSE ; 

    //return the return value 
    return($returnVal) ; 
} 


################################################ 
# Function: Sessions_delete 
# Parameters: $SessionID (string) 
# Returns: bool 
# Description: This function is used to delete the session 
################################################ 
function Sessions_destroy($SessionID) { 

    include_once('DBE.class.php') ; 
    $dbe = new DBE() ; 

    $query = "DELETE FROM Sessions WHERE SessionID = '$SessionID' " ; 

    $dbe->Delete($query) ; 

    return(TRUE) ; 
} 

################################################ 
# Function: Sessions_delete 
# Parameters: $SessionID (string) 
# Returns: bool 
# Description: This function is used to delete the session 
################################################ 
function Sessions_gc($aMaxLifetime) { 

    include_once('DBE.class.php') ; 
    $dbe = new DBE() ; 

    $query = "DELETE FROM Sessions WHERE (UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(LastUpdated)) > $aMaxLifetime " ; 

    $dbe->Delete($query) ; 

    return(TRUE) ; 
} 

    session_set_save_handler("Sessions_open", "Sessions_close", 
           "Sessions_read", "Sessions_write", 
           "Sessions_destroy", "Sessions_gc") ; 

?> 

我认为这是改变会议的基本功能,但我不太确定。这会导致我在重置会话中的模板时遇到麻烦。任何人有任何想法或知道我能做些什么来解决这个问题。我完全被难住,所以任何帮助,不胜感激。

回答

4

我不知道如果是这样的问题,但是这是跳了出来,当我看了你的代码:

你的序列化对象依赖于一个MySQL连接上

$模板=新模板( $ mysqli的);

,而你的对象(也许)可以序列化和取消序列化没有问题,MySQL连接不能,所以你非系列化$模板尝试对无效连接/文件句柄操作。

你可以尝试重新连接你的未序列化的对象到一个有效的数据库连接。

不知道你的模板类里面有什么(以及它使用什么资源和如何)很难猜测出什么问题,但我希望这是一个足够好的线索,从哪里开始寻找。

为了给你什么,我说什么更好的主意,考虑一下:

的template.php

<?php 

class Template { 
function __construct($c) { 
    $this->conn = $c; 
    $this->foo = "bar"; 
} 
function get_data() { 
    $result = mysql_query("select 1234 as test", $this->conn); 
    $data = mysql_fetch_array($result); 
    return $data; 
} 

function attach_db($c) { 
    $this->conn = $c; 
} 
} 

?> 

first.php

<?php 
session_start(); 
require('template.php'); 

$conn = mysql_connect('localhost', 'root', ''); 
$template = new Template($conn); 
?> 
<pre> 

Your $template var, freshly created: 
<?php var_dump($template); ?> 

Accessing the resources: 
<?php var_dump($template->get_data()); ?> 

<?php 
$_SESSION['template'] = serialize($template); 
?> 

</pre> 

等。PHP

<?php 
session_start(); 
require('template.php'); 

$template = unserialize($_SESSION['template']); 
?> 
<pre> 

Unserialized $template: 
<?php var_dump($template); ?> 
(notice that $template->foo === "bar" so your session un/serialization is working correctly) 

Accessing the (now invalid) mysql resources: 
<?php var_dump($template->get_data()); ?> 

</pre> 

调用first.php应该给你:

你的$模板变种,新创建:
对象(模板)#1(2){
[ “conn将”] =>
资源(3)型的(MySQL的链路)
[ “foo” 的] =>
串(3) “栏中的”
}

访问资源:
阵列(2){
[0] =>
串(4) “1234”
[ “测试”] =>
串(4) “1234”
}

调用others.php应导致:

反序列化$模板:
对象(模板)#1(2){
[ “conn将”] =>
INT(0)
[ “foo” 的] =>
串(3) “栏中的”
}
(通知即$模板 - >富===所以你的会话联合国/序列化工作正常)

访问(现已无效)MySQL的资源“栏”:

警告:请求mysql_query():提供的参数是不是一个第9行的template.php中的有效MySQL-Link资源

警告:mysql_fetch_array():提供的参数是没有的template.php一个有效的MySQL结果资源在第10行

布尔(假)

为了解决这个你可以重新创建资源不能被解除/序列化。
像这样:

solution.php

<?php 
session_start(); 
require('template.php'); 

$template = unserialize($_SESSION['template']); 
?> 
<pre> 

Unserialized $template: 
<?php var_dump($template); ?> 

Attaching a valid db connection: 
<?php 
$conn = mysql_connect('localhost', 'root', ''); 
$template->attach_db($conn); 
var_dump($template); 
?> 

Accessing the resources: 
<?php var_dump($template->get_data()); ?> 

</pre> 

现在,在被称为第一后调用solution.php。PHP应该给你:

序列化$模板:
对象(模板)#1(2){
[ “conn将”] =>
INT(0)
[ “foo” 的] =>
串(3) “栏中的”
}

附加一个有效的数据库连接:
对象(模板)#1(2){
[ “conn将”] =>
资源(3)式的(MySQL的链路)
[ “foo” 的] =>
串(3) “栏中的”
}

访问资源:
阵列(2){
[0] =>
串(4) “1234”
[ “测试”] =>
串(4) “1234”
}

正如我所说,不知道你的模板类是做什么的,不可能肯定发生了什么事......这只是一种可能性;)

祝你好运!

0

那么,你应该能够检查数据库,看看你的数据如何存储(如果有的话)。这当然是我要开始的地方。

1

看起来他们正在重写标准会话处理程序来将会话数据存储在数据库中。

查看Sessions表并查看您的序列化对象是否正确存储。

0

您的AJAX调用可能不包含会话cookie数据,并且正在写入其他会话。

您能否使用Fiddler并确定发送的确切请求?