PHP全局变量未导入会话处理程序

时间:2009-09-21 06:50:09

标签: php adodb-php

我正在使用ADOdb。出于某种原因,实际的$db未在'write'函数中导入。

该函数用于导入$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'函数中导入?

我该如何解决问题?

7 个答案:

答案 0 :(得分:5)

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

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

所以我的想法就是拥有这样的析构函数:

function __destruct() {
    session_write_close();
}

因此可以在写入和放大中使用对象。关闭处理程序。

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

答案 1 :(得分:0)

要么不将$db指定为全局,要么为其指定空值。

答案 2 :(得分:0)

我不是PHP专家,但也许你会覆盖它。在

之前和之后尝试$ db的回声

全球$ db;

并且:你确定你为$ db分配了什么(在查看函数内部的值之前)?

答案 3 :(得分:0)

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

答案 4 :(得分:0)

您似乎无法在上述代码中的任何位置初始化$db

我希望在某个地方看到$db = new ADO("myserver,mydb,user,password")电话 在代码中。

答案 5 :(得分:0)

尝试以下两件事:

  1. 分配

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

    而不是

    $db=...;
    

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

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

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

答案 6 :(得分: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'];