所以問題是,當調用/ 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的開始,同時添加一個公共登錄函數。
結果是每個頁面都可以登錄某人;不過,我覺得這是不好的做法。我看到的問題是,無論用戶是否登錄,每一個頁面調用都將啓動一個會話。我感覺這很糟糕,有什麼建議嗎?