PHP中的局部变量覆盖会话变量

Pac*_*tti 3 php mysql object

嗨,我在PHP页面遇到了一些问题:我正在使用教程编写一个小CMS .我设法写一个我用来与菜单交互的类,一切都运行良好:我可以在一个页面中插入,删除和获取菜单的所有项目,我可以重新排序它们.当我开始为用户编写相同的页面时,我遇到了一个问题:我正在使用Sentry类来验证每个页面中的用户:

require_once('../includes/Sentry.php');  
$theSentry = new Sentry();  
if (!$theSentry->checkLogin(1) ){ header("Location: index.php"); die(); }
Run Code Online (Sandbox Code Playgroud)

现在:如果我单独使用此验证,页面运行良好,但我需要查询数据库并提取user_admin.php页面中的所有用户:

require_once('../includes/DbUser.php');
$user_connector = new DbUser();
$all_users = array();
$all_users = $user_connector->getUserArray();
foreach($all_users as $id => $user){ echo " ... " };
Run Code Online (Sandbox Code Playgroud)

如果我评论这两个部分中的一部分,一切都运行良好,但是如果我让这个代码一起运行,页面就会正确创建,但下次我使用Sentry类运行一个页面时,我会被重定向到登录页面错误.Sentry类使用Validator类来检查凭据,此类中的方法报告数组输入而不是单个值输入.

我的问题是:如何可能从两个不同的类创建两个不同的对象,可以交互产生这样的问题?我想你需要两种方法的代码:

class Sentry {

...

function checkLogin($group=9,$user='',$pass='',$goodRedirect='',$badRedirect='') {
        // Include database and validation classes, and create objects
        require_once('DbConnector.php');
        require_once('Validator.php');
        $validate = new Validator();
        $loginConnector = new DbConnector();

        // If user is already logged in then check credentials
        if ($_SESSION['user'] && $_SESSION['pass']){

            // Validate session data
            if (!$validate->validateTextOnly($_SESSION['user'])){return false;}
            if (!$validate->validateTextOnly($_SESSION['pass'])){return false;}

            if ($_SESSION['gruppo'] <= $group){
                // Existing user ok, continue
                if ($goodRedirect != '') { 
                    header("Location: ".$goodRedirect) ;
                }           
                return true;
            }else{
                // Existing user not ok, logout
                //$this->logout();
                header("Location: low_perm.php");
                die;
                //return false;
            }

        // User isn't logged in, check credentials
        }else{  
            // Validate input
            if (!$validate->validateTextOnly($user)){return false;}
            if (!$validate->validateTextOnly($pass)){return false;}

            // Look up user in DB
            $getUser = $loginConnector->query("SELECT * FROM `utenti` WHERE `usr` = '".$user."' AND `psw` = PASSWORD('".$pass."') AND `gruppo` <= ".$group." AND `attivo` = 1");
            $this->userdata = $loginConnector->fetchArray($getUser);

            if ($loginConnector->getNumRows($getUser) > 0){
                // Login OK, store session details
                // Log in
                $_SESSION["user"] = $user;
                $_SESSION["pass"] = $this->userdata['pass'];
                $_SESSION["gruppo"] = $this->userdata['gruppo'];

                if ($goodRedirect) { 
                    header("Location: ".$goodRedirect);
                }
                return true;

            }else{
                // Login BAD
                unset($this->userdata);
                if ($badRedirect) { 
                    header("Location: ".$badRedirect) ;
                }       
                return false;
            }
        }           
    }
}
Run Code Online (Sandbox Code Playgroud)

这是获取用户的功能:

class DbUser extends DbConnector{

...

    function getUserArray() {
        while ($row = mysql_fetch_object($this->user_result)) {
            $this->users[$row->id] = $row;
        }
        return $this->users;    
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道这是一个难以解释的问题,所以如果我需要指定其他内容,请告诉我......谢谢

编辑:错误在Validator类和此函数(与preg_match()行):

function validateTextOnly($theinput,$description = ''){
    $result = preg_match ("/^[A-Za-z0-9\ ]+$/", $theinput );
    if ($result AND $theinput!=''){
        return true;
    }else{
        $this->errors[] = $description;
        return false; 
    }
}
Run Code Online (Sandbox Code Playgroud)

伟大的新闻:我发现了错误的位置,但我无法理解为什么这段代码不起作用:

$user_connector = new DbUser();
$all_users = array();
$all_users = $user_connector->getUsers();
foreach($all_users as $id => $user){ ... }
Run Code Online (Sandbox Code Playgroud)

foreach语句是关键点:当我使用$all_useras时$id=>$user,它实际上用循环中使用的最后一个对象("用户"对象)覆盖$ _SESSION ['user']的内容.任何人都可以解释一下局部变量如何覆盖会话?我想说清楚:我解决了问题(改变$id => $user$id => $userObj),但我正在寻找解释.谢谢!

skj*_*las 5

我和你有完全相同的问题,在我的情况下,这是因为PHP的寄存器全局变量被打开了.

注册globals是一个php配置设置,它为$ _SESSION中设置的每个变量创建一个局部变量.这意味着当你设置$ _SESSION ['user']时,也会为你创建一个局部变量$ user.如果您在代码中覆盖此变量,正如您所报告的那样,新值也将在$ _SESSION中设置.有关寄存器全局变量的更多信息,请查看此处.

要关闭此设置,您必须编辑为正在使用的Web服务器加载的php.ini文件,并将register_globals设置为Off,然后重新启动Web服务器.请记住,如果您计划在任何其他Web服务器上运行此代码,则必须关闭此设置才能使代码正常运行.