PHP和MVC导航菜单错误-菜单在登录时不会更改,但在刷新时会更改


PHP and MVC Navigation Menu Bug - Menu Does not Change On Login, but does on refresh

我目前正在为一个web应用程序做一个辅助项目。我正在使用PHP,并试图遵循MVC类型的模式(不使用任何框架),我无法在导航栏中正确显示菜单。预期功能是用户将访问该网站并使用其信息登录。每个用户都有一个权限级别,用于驱动他们可以访问的导航菜单类型。

我现在让网站工作的方式是,当用户登录时,它会将他们的用户名和权限级别放入$_SESSION全局。负责显示导航的默认布局(layout.php)在检查应该使用什么样的导航菜单后,通过require_once进入页面。无论出于何种目的,设置都在工作,只是不是我想要的。登录后,导航菜单保持不变,直到刷新页面或选择菜单选项。

我试着追踪这个问题,但由于对PHP和MVC都很新,我不太清楚在哪里解决这个问题。我知道每当控制器选择一个视图时,layout.php都会进行渲染。在呈现之前,但在登录控制器完成之后,必须设置$_SESSION全局中的角色。我尝试过通过PHP和JavaScript进行页面刷新,但这是一次永久刷新(不断循环),尽管这是一个快速修复,但感觉不是正确的修复方法。希望有人能想到我没有想到的东西,或者给我指明正确的方向。以下是登录过程中使用的代码的代码片段。

index.php-这是网站的"前端",一切都从这里开始,用户也从这里登陆。

if (isset($_SESSION["username"]) && array_key_exists("username", $_SESSION)) {
    session_destroy();
} else {
    session_start();
}
require_once('connection.php');
if (isset($_GET['controller'])) {
    $controller = $_GET['controller'];
    if (isset($_GET['action'])) {
        $action = $_GET['action'];
    } else {
        $action = 'index';
    }
} else {
    $controller = 'login';
    $action = 'login';
}
require_once('views/layout.php');

布局.php

<?php
    $nav = "";             
    if (isset($_SESSION['username']) && array_key_exists("username", $_SESSION)) {
        if ($_SESSION['role'] == 1) {
            $nav = "admin_nav.php";
        } else if ($_SESSION['role'] == 2) {
            $nav = "prof_nav.php";
        } else if ($_SESSION['role'] == 3) {
            $nav = "student_nav.php";
        } else {
            $nav = "guest_nav.php";
        }
    } else {
        $nav = "default_nav.php";
    }           
?>
<!DOCTYPE html>
<html>
    <head>
        <title>Auto-Grader</title>
        <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
        <link rel="stylesheet" href="styles/site.css">
    </head>
    <body>    
        <div id="header">
            <div id="header-top">
            </div>
            <div id="header-bottom">
            </div>
        </div>
        <div id="navigation-wrapper">
            <?php require_once($nav); ?>
        </div>        
        <div id="content-wrapper">
            <?php require_once('routes.php'); ?>
        </div>
        <footer>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
        <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
        </footer>
    </body>
</html>

登录控制器

class LoginController {
    public function login() {
        require_once('views/login/index.php');
    }
    public function validateLogin() {
        require_once('models/login_validator.php');
        $email = $_POST['email'];
        $password = $_POST['password'];
        $isValid = LoginValidator::validateLogin($email, $password);
        $username = $isValid['username'];
        if ($isValid) {
            # Show home/landing page view
            require_once('views/home/index.php');
        } else {
            require_once('views/login/failure.php');
        }
    }
    public function logout() {
        unset($_SESSION['username']);
        unset($_SESSION['role']);
        session_destroy();
        # Redirect to homepage on logout
        echo "<script> window.location.assign('index.php') </script>";
    }
}

登录模型(首先设置$_SESSION全局)

class LoginValidator {
    public static function validateLogin($email, $password) {
        $db = Db::getInstance();
        $userQuery = $db->prepare('SELECT * FROM users WHERE email = :email AND pwd = :password');
        $userQuery->execute(array('email' => $email, 'password' => $password));
        $user = $userQuery->fetch(PDO::FETCH_ASSOC);
        if (!$user) {
            return false;
        } else {
            $_SESSION['username'] = $user['username'];
            $_SESSION['role'] = $user['perm_id'];
            return true;
        }
    }
}

感谢您的意见,如果还有其他作品需要看,我很乐意编辑并提供。

您需要通过应用程序跟踪执行情况。如果会话var是在创建导航后设置的,那么它将不起作用。如果是这样,则需要在创建视图之前处理任何后期事件。

您在以下代码中有一个错误:

if (isset($_SESSION["username"]) && array_key_exists("username", $_SESSION)) {
    session_destroy();
} else {
    session_start();
}

session_start填充$_SESSION超全局,因此第一个条件永远不能返回true。