0

我正在使用 ADOdb。出于某种原因,实际$db并未在“写入”函数中导入。

该函数旨在导入$db的实际值。相反,它将一个空值分配给$db

<?php
// load ADODB class
include(DIR_WS_CLASSES . "adodb5/adodb.inc.php");

$db = NewADOConnection(DB_TYPE);
$db->Connect(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD, DB_DATABASE);


class SessionManager {
    var $life_time;

    function SessionManager(){
        global $db;
        // Read the maxlifetime setting from PHP
        $this->life_time = get_cfg_var("session.gc_maxlifetime");

        // Register this object as the session handler
        session_set_save_handler(array(&$this, "open"), 
                                array(&$this, "close"), 
                                array(&$this, "read"), 
                                array(&$this, "write"), 
                                array(&$this, "destroy"), 
                                array(&$this, "gc"));
    }

    function open($save_path, $session_name){
        global $sess_save_path;
        global $db;

        $sess_save_path = $save_path;

        return true;
    }

    function close(){
        global $db;
        return true;
    }

    function read($id){
        global $db;
        // Set empty result
        $data = '';

        // Fetch session data from the selected database
        $time = time();
        $newid = $db->qstr($id, get_magic_quotes_gpc());

        $sql = "SELECT session_data 
                FROM sessions 
                WHERE session_id = $newid 
                AND expires > $time";

        $rs = $db->Execute($sql) or die($db->ErrorMsg());
        $a = $rs->RecordCount();

        if($a > 0){
            $data = $rs->fields['session_data'];
        }

        return $data;
    }

    function write($id, $data){
        global $db;
        // Build query                
        $time = time() + $this->life_time;
        $newid = $db->qstr($id, get_magic_quotes_gpc());
        $newdata = $db->qstr($data, get_magic_quotes_gpc());
        $sql = "REPLACE sessions
                (session_id, session_data, expires) 
                VALUES($newid, $newdata, $time)";

        $rs = $db->Execute($sql) or die($db->ErrorMsg());

        return TRUE;
    }

    function destroy($id){
        global $db;
        // Build query
        $newid = $db->qstr($id, get_magic_quotes_gpc());
        $sql = "DELETE FROM sessions 
                WHERE session_id = $newid";

        $db->Execute($sql) or die($db->ErrorMsg());

        return TRUE;
    }

    function gc(){
    // Garbage Collection
        global $db;
        // Build DELETE query.  Delete all records that passed expiration time
        $sql = "DELETE FROM sessions 
                WHERE expires < UNIX_TIMESTAMP()";

        $db->Execute($sql) or die($db->ErrorMsg());

        // Always return TRUE
        return true;
    }
}


// initialize session
$sess = new SessionManager();
session_start();
?>

为什么$db'write'函数中没有实际导入?

我该如何解决这个问题?

4

7 回答 7

6

为那些不听评论的人编辑;)

“从 PHP 5.0.5 开始,写入和关闭处理程序在对象销毁后调用,因此不能使用对象或抛出异常。但是对象析构函数可以使用会话。可以从析构函数调用 session_write_close() 来解决这个问题鸡蛋问题”

所以想法是有一个像这样的析构函数:

function __destruct() {
    session_write_close();
}

这样对象就可以在 write & close 处理程序中使用。

然后,为了安全起见,在 write & close 中重新实例化 $db,因为全局 $db 析构函数很可能在 SessionHandler 之前调用。

于 2009-09-21T07:12:42.703 回答
0

要么不分配$db为全局,要么分配一个空值。

于 2009-09-21T06:53:56.887 回答
0

我不是 PHP 专家,但也许你正在覆盖它。在之前和之后尝试 $db 的回声

全局$db;

并且:您确定您为 $db 分配了任何东西(在查看函数内部的值之前)?

于 2009-09-21T06:57:43.417 回答
0

在函数内外尝试 $db 上的 var_dump。

于 2009-09-21T07:09:03.877 回答
0

$db您似乎没有在上面的代码中的任何地方初始化。

我希望$db = new ADO("myserver,mydb,user,password")在代码中的某处看到一个调用。

于 2009-09-21T07:35:28.660 回答
0

试试这 2 件事:

  1. 分配

    $GLOBALS['db']=...;
    

    代替

    $db=...;
    

    在您的全局脚本中。然后在您的函数中将其引用为$db=$GLOBALS['db'];.

    原因:您可能$db在某个非全球性的地方进行分配。

  2. 让它成为你班级的私有财产。提供 getter,但不提供 setter。而是从您的构造函数中设置它。

于 2009-09-21T07:45:35.613 回答
0

我很确定是什么问题。当此文件包含在全局范围内时,您的代码将正常工作。但是考虑一下:

$a=1;
function displaya()
{
    global $a;
    var_dump($a);
}

当您运行此文件时,您将看到int(1)输出。

但考虑另一个文件:

function abc()
{
include("above-stated-file.php");
displaya();
}

abc();

现在它将显示NULL.

原因是在第二个文件中。您的第一个文件包含在本地上下文中,而不是全局上下文中。这就是为什么global $a不起作用。

将其更改为:

$GLOBALS['a']=....;

当你使用它时:$a=$GLOBALS['a'];

于 2009-09-21T07:54:20.057 回答