Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Local variable overwrite session variable in PHP

Tags:

object

php

mysql

Hi I'm having some problem with a PHP page: I'm writing a little CMS using this tutorial. I manage to write a class I use to interact with menus and all is working well: I can insert, delete and get all items of the menu in a page where I can reorder them. When I started to write the same page for users, I encountered an issue: I'm using a Sentry class to validate users in each page:

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

Now: if I use this validation alone, the page is working well, but I need to query the database and extract all the user in the user_admin.php page:

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

If I comment one of the two section, all is working well, but if I leave this code running together, the page is correctly created, but next time I run a page using the Sentry class, I'm redirected to login page with an error. The Sentry class use a Validator class to check credentials, and a method in this class is reporting an array input instead of a single value input.

My question is: how can be possible that two different objects created from two different classes, can interact generating such a problem? I think you need the code of the two method:

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;
            }
        }           
    }
}

And this is the function to get the users:

class DbUser extends DbConnector{

...

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

I know it's a difficult-to-explain question, so let me know if I need to specify something else... Thanks

EDIT: The error is in Validator class and in this function (the line with 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; 
    }
}

GREAT NEWS: I found where the error was, but I'm not able to understand why this code doesn't work:

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

The foreach statement is the point: when I'm using $all_user as $id=>$user, it actually overwrite the content of $_SESSION['user'] with the last object used in the cycle (an "user" object). Anyone can explain me how a local variable can overwrite a session one? I would like to make it clear: I solve the problem (changing $id => $user with $id => $userObj), but I'm looking for an explanation. Thanks!

like image 227
Paciotti Avatar asked Sep 08 '26 05:09

Paciotti


1 Answers

I had the exact same problem as you, and in my case it was because PHP's register globals was turned on.

Register globals is a php configuration setting that creates a local variable for each variable that is set in $_SESSION. This means that when you set $_SESSION['user'], a local variable $user will also be created for you. If you overwrite this variable in you code, as you reported, the new value will also be set in $_SESSION. For more info on register globals, look here.

To turn this setting off, you must edit the php.ini file which is loaded for the web-server you are using, and set the register_globals setting to Off, and then restart your web-server. Remember that if you plan to run this code on any other web-server, this setting will also have to be turned off for your code to function properly.

like image 115
skjerdalas Avatar answered Sep 10 '26 10:09

skjerdalas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!