0

我面临的问题有两个方面:

  1. 我想使用我的会话包装类作为跨多个页面创建会话的一种方式。
  2. 想要一种在设置超时后使上述会话过期的方法。

作为一个示例用例,如果我的站点在访问页面之前需要身份验证,我将创建我的会话包装器的实例,如果用户的凭据有效,那么我会将它们重定向到帐户页面。

// index.php
if (invalidUser) {
   // Show error
} else if(userIsValid($user_email, $user_pass)) {
   $sess = new Session("MySite", 10);
   Utils::redirect("accountPage.php"); 
}

这是重定向到帐户页面的实用程序方法:

// utils.php
ob_start(); // Start output buffer
/**
  * Redirects the HTTP header to another location.
  *
  * @param (String) $address the new location to send the browser.
  */
  public static function redirect($address) {
     header("Location: $address");
     exit();
  }

这是会话包装类的实现:

// session.php
class Session {        
       /**
         * Default Constructor.
         *
         * @param (String) $name the name of the session, as well as the session cookie name 
         * @param (String) $timeout the amount of time to permit the existence of 
         * this session.
         * -1, indicates that the session should live on indefinetely.
         */
        function __construct($name, $timeout = -1) {
            session_name($name);
            session_start();

            $_SESSION["timeout"] = $timeout;
            $_SESSION["created"] = time();
        }

    /**
     * Determines if the session is still considered "alive" based on its 
     * timeout + creation time.
     * If the session has expired we remove the session effectively "Timing out".
     */
    public static function isExpired() {

        // Default infinite timeout case
        if ($_SESSION["created"] == -1) {
            return false;
        }

        // Evaluate time left on session
        if(($_SESSION["timeout"] + $_SESSION["created"]) <= time()) {
            // Remove Session
            return true; 
        } else {
            // Session has not expired yet
            return false;
        }
    }
}

我希望$_SESSION global此页面上的数组内有数据,但它的NULL. 我读过类似的帖子,但我想我的具体实现遗漏了一些东西。

// accountsPage.php
<?php
include_once("session.php");

Session::isExpired(); => false
print_r($_SESSION); => NULL

我知道它部分有效,因为如果我不重定向然后打印$_SESSION global数组,其中就有数据。我知道session_start()在每个页面的开头添加,但我想减轻创建额外的会话和 cookie。

任何帮助都会非常感谢!

4

2 回答 2

1

由于未找到请求的 $_SESSION 的索引并且它不在相同的session_name下,因此您Session::isExpired的行为是正确的。FALSE

假设在您调用的第一页上new Session('MyWebsite', 10);。在其他页面中,您需要在开始会话之前调用MyWebsite会话名称并获取 $_SESSION 值。

如果开发人员未指定需要调用哪个会话名称,则会话名称将为每个新请求重置为默认名称。这就是它会返回的原因null。我正在稍微更改您的代码。

function __construct($name, $timeout = -1) {
   session_name($name);
   session_start();

   if(!isset($_SESSION['created'])) {
      $_SESSION["timeout"] = $timeout;
      $_SESSION["created"] = time();
   }
}

public function isExpired() {
   /* your code here */
}

我正在从 isExpired() 中获取静态,静态没有调用类构造函数。第二页的示例

<?php
include('session.php');

$session = new Session('MyWebsite', 10);
$session->isExpired();
print_r($_SESSION);
于 2013-06-08T19:48:06.163 回答
0

您必须session_start()在发送每个页面的输出之前调用。对于“accountsPage.php”,您确实包含了“session.php”文件,但该文件只定义了类,它实际上并没有调用此函数,除非您new Session("MySite", 10);的页面代码中有某个位置。

我建议您实际删除session_name($name);session_start();删除__construct它们,而是将它们放在“session.php”脚本的顶部。显然,您将需要替换$name"MySite"(硬编码),但有一些方法可以解决这个问题。

于 2013-06-08T18:04:15.707 回答