0

我知道这是一个常见的问题,但我已经经历了很多其他的答案,并且无法理解为什么这仍然失败。所以,我很抱歉,但希望有人能指出哪里出了问题!

index.php中,执行以下代码:

// Set Database Configuration
$dbconfig = array( 
    'host' => getenv('MYSQL_DB_HOST'),
    'user' => getenv('MYSQL_USERNAME'), 
    'pass' => getenv('MYSQL_PASSWORD'), 
    'name' => getenv('MYSQL_DB_NAME') 
); 

// Start database sessions
$db = oadb::getInstance();
$db->show_errors();
echo $db->prepare("hello");

// Open a new session
$sess = new oasession();
session_start();

getInstance() ; 并且$db->prepare()发生没有问题,并且回显“hello”文本以确认这一点。

当调用新的 oasession()时,车轮开始脱落。oasessions ()函数是一个会话处理程序,它接管 PHP 的正常会话处理,并将其放入 MySQL 数据库中。

session.inc.php包含一个类如下(我删除了一些不相关的函数):

class oasession {

   var $life_time;

   function oasession() {

      // 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;
        $sess_save_path = $save_path;
        // Don't need to do anything. Just return TRUE.
        return true;
   }

   function read( $id ) {
       global $db;

           // Set empty result
           $data = '';

           // Fetch session data from the selected database

           $time = time();

           $newid = $db->prepare($id);
           $sql = "SELECT `session_data` FROM `OA-Auth_sessions` WHERE `session_id` = '$newid' AND `expires` > $time";

           $rs = $db->query($sql);                           
           $a = $db->num_rows($rs);

           if($a > 0) {
             $row = $db->fetch_array($rs);
             $data = $row['session_data'];
           }
           return $data;
        }

    function write( $id, $data ) {
        global $db;

         // Build query                
         $time = time() + $this->life_time;

         $newid = $db->prepare($id);
         $newdata = $db->prepare($data);

         $sql = "REPLACE `OA-Auth_sessions` (`session_id`,`session_data`,`expires`) VALUES('$newid', '$newdata', $time)";

         $rs = $db->query($sql);

         return TRUE;

      }
}

它能够毫无问题地使用 read($id) 函数,但是当它尝试使用 write($id, $data) 函数时,它会失败并出现以下错误...

Fatal error: Call to a member function prepare() on a non-object in sessions.class.php on line 66

...建议从 $db->prepare() 执行的准备函数不是有效对象。

我已经尝试通过在新的 oasession() 之前和之后放置 print_r() 来测试这一点,并且两者都打印了对象描述,并且在新的之前或之后运行其他 $db->prepare() 调用没有问题oasession() 调用。

关于可能导致此问题的任何想法?

非常感谢!

4

1 回答 1

0

根据php.net,设法解决了这个问题:

当使用对象作为会话保存处理程序时,向 PHP 注册关闭函数非常重要,以避免 PHP 在关闭时内部销毁对象的方式产生意外的副作用,并可能阻止调用 write 和 close。通常,您应该使用 register_shutdown_function() 函数注册“session_write_close”。

将以下内容添加到 sessions.class.php oasession() 函数...

register_shutdown_function('session_write_close');

...解决了所有问题:)

于 2012-08-05T17:53:40.273 回答