从PHP4到PHP5:会话处理程序可以';t访问全局DB对象


From PHP4 to PHP5:session handler can't access global DB object

我正在将一个多年前用PHP 4.4编写的PHP应用程序迁移到一个运行PHP 5.3的新主机上。该应用程序仅使用PEAR库编写,没有使用其他框架。我发现以下问题:我在主页上有这个代码:

require_once('DB.php'); //the PEAR DB package
$db=DB::connect("mysql://usuario:@localhost/databasename");
if (DB::isError($db)) {
    die("MEEEEEPT");
    }
//Inicia sesión
session_set_save_handler("Sesion_Open", "Sesion_Close", "Sesion_Read", "Sesion_Write", "Sesion_Delete", "Sesion_Clean");
session_name("misesion");
session_start();

然后,会话处理程序是:

function Sesion_Open() {
    global $db;
    if (DB::isConnection($db)) { return true; }
    else { return false; }
    }
function Sesion_Close() {
    global $db;
    $db->disconnect();
    return true;
    }
function Sesion_Read($id) {
    global $db;
    $resultado=$db->query("SELECT datos FROM sesiones WHERE id='$id'");
    $num=$resultado->numRows();
    if ($num > 0) {
        $row=$resultado->fetchRow(DB_FETCHMODE_ASSOC);
        $resultado->free();
        return $row['datos'];
        }
    else {
        $resultado->free();
        return "";
        }
    }
function Sesion_Write($id, $datos) {
    global $db;
    $datos=addslashes($datos);
    $num=$db->getOne("SELECT COUNT(id) FROM sesiones WHERE id='$id'");
    if ($num > 0) {
        $sql="UPDATE sesiones SET datos='$datos', tiempo=now() WHERE id='$id'";
        }
    else {
        $sql="INSERT INTO sesiones (id, tiempo, datos) VALUES ('$id', now(), '$datos')";
        }
    $resultado=$db->query($sql);
    if (DB::isError($resultado)) { return false; }
    else { return true; }
    }

如果我试图在会话中保存一些数据,使用,比如:

$_SESSION['bkla']="Doremifa";

它没有被保存:DB会话表仍然是空的,我在日志中得到一个错误:

 PHP Fatal error:  Call to a member function getOne() on a non-object in sesiones.php on line 45

参考"Sesion_Write"中我尝试在表上执行SELECT的那一行。

据我所见,"Sesion_Open"函数可以正确访问$db对象,但其他函数看不到;这个物体对他们来说似乎并不存在。怎么回事?我已经有几年没有接触过PHP了,所以我不知道是PHP4和PHP5之间发生了什么变化导致了这种情况,还是其他原因。

啊,找到了答案:

将带有回调的会话从php4迁移到php5-的奇怪行为

您需要手动调用session_write_close(),或者将其注册为关闭函数:register_shutdown_function("session_write_close")