【问题标题】:Session variable does not preserves the value on next page in php with MongoDB?会话变量不会在 php 中使用 MongoDB 保留下一页上的值?
【发布时间】:2014-10-21 09:30:23
【问题描述】:

我正在使用 PHP 和 MongoDB 实现一个简单的会话管理器。 但不知何故,$_SESSION 在下一页上是空的,但在第一页上分配了值..

class SessionManager
{

//name of collection where sessions will be stored
const COLLECTION = 'sessions';
//Expire session after 10 mins in inactivity
const SESSION_TIMEOUT = 600;
//Expire session after 1 hour
const SESSION_LIFESPAN = 3600;

//name of session cookie
const SESSION_NAME = 'mongosessid';
const SESSION_COOKIE_PATH = '/';

const SESSION_COOKIE_DOMAIN = '';

private $_mongo;
private $_collection;

//Represent the current session
private $_currentSession;

function __construct()
{
    $this->_mongo = DBConnection::instantiate();
    $this->_collection = $this->_mongo->getCollection(SessionManager::COLLECTION);

    session_set_save_handler(
        array(&$this, 'open'),
        array(&$this, 'close'),
        array(&$this, 'read'),
        array(&$this, 'write'),
        array(&$this, 'destroy'),
        array(&$this, 'gc')
    );

    //Set session garbage collection period
    ini_set('session.gc_maxlifetime', SessionManager::SESSION_LIFESPAN);

    //Set session cookie configurations
    session_set_cookie_params(
        SessionManager::SESSION_LIFESPAN,
        SessionManager::SESSION_COOKIE_PATH,
        SessionManager::SESSION_COOKIE_DOMAIN
    );

    //Replace  'PHPSESSID' with 'mongosessid' as the
    // session name
    session_name(SessionManager::SESSION_NAME);
    session_cache_limiter('nocache');
    register_shutdown_function('session_write_close');
    // start the session
    session_start();
}

public function open($path, $name)
{
    return true;
}

public function close()
{
    return true;
}

public function read($sessionId)
{
    $query = array(
        'session_id' => $sessionId,
        'timedout_at' => array('$gte' => time()),
        'expire_at' => array('$gte' => time() - SessionManager::SESSION_LIFESPAN)
    );
    $result = $this->_collection->findOne($query);
    $this->_currentSession = $result;

    if (!isset($result['data'])) {
        return '';
    }
    return $result['data'];
}

public function write($sessionId, $data)
{
  //  $expired_at = time() + self::SESSION_TIMEOUT;
    $new_obj = array(
        'data' => $data,
        'timedout_at' => time() + self::SESSION_TIMEOUT,
        'expired_at' => (empty($this->_currentSession)) ?
                time() + SessionManager::SESSION_LIFESPAN
                : $this->_currentSession['expired_at']
    );
    $query = array('session_id' => $sessionId);
    $this->_collection->update(
        $query,
        array('$set' => $new_obj),
        array('upsert' => true)
    );
    return true;
}

public function destroy($sessionId)
{
    $this->_collection->remove(array('session_id' => $sessionId));
    return true;
}

public function gc()
{
    $query = array('expired_at' => array('$lt' => time()));
    $this->_collection->remove($query);
    return true;
}

}

// initiate the session
$session = new SessionManager();

接下来我创建了 2 个新脚本来测试这个sessionManager Mongo_session1.php

<?php
 // Session started by requiring the script
 require('session.php');
 // Generate random number
 $random_number = rand();
 //Put the number into session
 $_SESSION['random_number'] = $random_number;
?>
<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="css/style.css"/>
  <title>Using SessionManager ... Page 1</title>

  </head>
  <body>
     <p> Random number generated
        <span style="font-weight: bold">
            <?php echo $_SESSION['random_number']; ?>
        </span>
     </p>
     <p>
        PHP session id
        <span style="text-decoration: underline">
            <?php echo session_id(); ?>
        </span>
    </p>
    <a href="mongo_session2.php">Go to Next page</a>
  </body>
</html>

Mongo_session2.php

<?php
    // Session started by requiring the script
    require('session.php');
?>
<!doctype html>
<html lang="en">
  <head>
     <meta charset="UTF-8">
     <link rel="stylesheet" href="css/style.css"/>
     <title>Using SessionManager ... Page 2</title>
  </head>
  <body>
       <h2>Using the SessionManager.. Page 2</h2>
       <p>The random number generated in previous page is still
         <span style="font-weight: bold">
           <?php
              echo "<pre>";
               print_r($_SESSION);
              echo "</pre>";
           ?>
         </span>
        </p>
        <p>
         PHP session id
          <span style="text-decoration: underline;">
            <?php echo session_id(); ?>
          </span>
         </p>
   </body>
</html>

如果你之前也遇到过同样的问题,并且得到了解决方案,那对我学习 MongoDB 和 PHP Web 开发会很有帮助。提前谢谢您。

【问题讨论】:

    标签: php mongodb session session-set-save-handler


    【解决方案1】:

    你有两个问题:

    首先,您使用了两个不同的变量名; "expire_at" 和 "expired_at" 这显然会导致查询失败。

    其次,我认为你的逻辑对于 expire/expired_at 的“读取”是错误的,应该是:

    'expire_at' => array('$gte' => time())
    

    ...您的 expired_at 值是按 time+LIFESPAN 计算的,因此您只需将其与 time() 进行比较即可查看它是否在未来。

    希望这会有所帮助。

    【讨论】:

    • @Hiren Chauhan - 如果它解决了您的问题,您应该接受答案。
    • 对不起,我忘记了
    猜你喜欢
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 2015-08-06
    • 1970-01-01
    • 2011-04-09
    • 2018-11-30
    • 1970-01-01
    相关资源
    最近更新 更多