2009-06-24 82 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並確定發送的確切請求?