2013-05-03 88 views
0

所以問題是,當調用/ MVCTest/manage/dashboard時,驗證器失敗,因爲authenticate(authenticator類中的方法)沒有找到$ _SESSION ['user_id'],所以它會將用戶踢回登錄頁面。PHP會話變量在控制器之間丟失

然而,如果我改變下面的動作: 行動=「?/ MVCTest /管理/登錄目標= MVCTest /管理/儀表板」

並添加相同的登錄功能構成索引控制器向manageController ,一切工作正常,但這意味着我將不得不在每個控制器有一個我想登錄的頁面(這是每個頁面,因爲我想要一個用戶儀表板)的登錄功能。

那麼如何獲得$ _SESSION來在控制器之間進行預設,以便我可以讓一個控制器負責記錄用戶輸入/輸出?

首先,一些代碼...

行動= 「/ MVCTest /索引/登錄?目標= MVCTest /管理/儀表板」 調用indexController的的登陸行動。

<?php 
    Class indexController Extends Core_Controller { 

    public function login(){ 
    $this->registry->authenticator->login($_POST); 
    } 
    } 
?> 

身份驗證器對象在引導程序中創建並分配給註冊表。現在用於驗證器對象。

<?php 
    Class Authenticator Extends Base_Model { 

    public function login($credentials){ 
    //Select user from the database based on email/username 
    try{ 
    $STH = $this->db->prepare("SELECT * FROM user_account WHERE email = ? OR username = ?"); 
    $STH->bindParam(1, $credentials['login']); 
    $STH->bindParam(2, $credentials['login']); 
    $STH->execute(); 
    while($user = $STH->fetch(PDO::FETCH_OBJ)){ 
     $password = $user->user_salt.$credentials['password']; 
     $password = $this->hashData($password); 
     try{ 
     if($password === $user->password){ 
      //Active and Verified user exists, set sessions 
      $random = $this->generateRandomString(); 
      //Build the token 
      $token = $_SERVER["HTTP_USER_AGENT"] . $random; 
      $token = $this->hashData($token); 

      //Setup session variables 
      session_start(); 
      $_SESSION["token"] = $token; 
      $_SESSION["user_id"] = $user->id; 

      //Delete old session records for the user 
      $STH = $this->db->prepare("DELETE FROM user_session WHERE user_account_id = ?"); 
      $STH->bindParam(1, $user->id); 
      $STH->execute(); 

      //Insert new session records for the user 
      try{ 
      $STH = $this->db->prepare("INSERT INTO user_session (user_account_id, session_id, token) 
             VALUES (?,'".session_id()."', ?);"); 
      $STH->bindParam(1, $user->id); 
      $STH->bindParam(2, $token); 
      $STH->execute(); 
      header("Location: /{$_GET['target']}"); 
      exit; 
      } catch (PDOException $e){ 
      file_put_contents(__SITE_PATH."/logs/errors/MySQLErrors", $e->getMessage()."\n", FILE_APPEND); 
      die($e->getMessage()); 
      }     
     } else { 
      throw new Exception("Password is incorrect!"); 
     } 
     } catch (Exception $e){ 
     file_put_contents(__SITE_PATH."/logs/errors/LoginErrors", $e->getMessage()."\n", FILE_APPEND); 
     die($e->getMessage()); 
     } 
    } 
    //Email/Username not found 
    throw new Exception("Email/Username not found!"); 
    } catch (Exception $e) { 
    file_put_contents(__SITE_PATH."/logs/errors/LoginErrors", $e->getMessage()."\n", FILE_APPEND); 
    die($e->getMessage()); 
    } catch (PDOException $e){ 
    file_put_contents(__SITE_PATH."/logs/errors/MySQLErrors", $e->getMessage()."\n", FILE_APPEND); 
    die($e->getMessage()); 
    } 
}  
} 
?> 

最後,我manageController

<?php 
    session_name(); 
    session_set_cookie_params(3600, "/MVCTest/manage/"); 
    session_start(); 

    Class manageController Extends Core_Controller { 

    public function index() { 
     if(isset($_SESSION['user_id'])){ 
     header("Location: /MVCTest/manage/dashboard"); 
     exit; 
     } 
     $this->registry->template->show('manage/index'); 
    } 

    public function dashboard(){ 
     $this->registry->authenticator->authenticate("/MVCTest/manage/");  
     $this->registry->template->show('manage/dashboard'); 
    } 
    } 
?> 

我找到了答案。離開session_name(); session_set_cookie_params(3600,__SITE_PATH。'/ MVCTest/manage /');在manageController中移動session_start();到擴展Core_Controller的開始,同時添加一個公共登錄函數。

結果是每個頁面都可以登錄某人;不過,我覺得這是不好的做法。我看到的問題是,無論用戶是否登錄,每一個頁面調用都將啓動一個會話。我感覺這很糟糕,有什麼建議嗎?

回答

1

看看這段代碼:

//Setup session variables 
session_start(); 
$_SESSION["token"] = $token; 
$_SESSION["user_id"] = $user->id; 

您必須使用

session_start(); 

在文件的開頭。

查看更多about session_start