会话数据未传递到其他页面

时间:2013-06-08 17:47:39

标签: session session-variables php

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

  1. 我想使用我的会话包装器类作为创建方法 跨多个页面的会议。
  2. 想要在设置超时后过期上述会话。
  3. 作为示例用例,如果我的站点在访问页面之前需要身份验证,我将创建会话包装器的实例,如果用户的凭据有效,那么我会将它们重定向到帐户页面。

    // 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。

    任何帮助都会提前感谢!

2 个答案:

答案 0 :(得分:1)

返回Session::isExpiredFALSE的行为正确,因为找不到请求的$ _SESSION的索引且它不在同一个session_name下。

让我们在第一页上说你叫new Session('MyWebsite', 10);。在其他页面中,您需要在开始会话和获取$ _SESSION值之前调用 MyWebsite 会话名称。

如果开发人员未指定需要调用哪个会话名称,则会话名称将重置为每个新请求的默认名称。这就是它返回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);

答案 1 :(得分:0)

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

我建议您实际从session_name($name);删除session_start();__construct,而不是将它们放在“session.php”脚本的顶部。显然,您需要将$name替换为"MySite"(硬编码),但有很多方法。