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!

Comments

Can we have the error message ?

Written by krifur

Of course, but I don't think is useful... Is an error about the Validator class: Warning: preg_match() expects parameter 2 to be string, object given in /web/htdocs/www.subamiata.it/home/nuovo/includes/Validator.php on line 21

Written by Paciotti

well, now show Validator.php and we will look at the 21 line.

Written by OZ_

The problem is not on line 21 of Validator.php. It is working for other pages! The problem is that $theSentry is interacting somehow with $user_connector. Both of them make a query to de 'utenti' table, but why are they interacting??? I'll add some code from Validator as post edit...

Written by Paciotti

It should be a session related problem because the only way to solve (temporarily) the problem is shut down the browser and reopen it. But in getUserArray() I'm not using session...

Written by Paciotti

bella italy....

Written by yes123

Accepted Answer

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.

Written by skjerdalas
This page was build to provide you fast access to the question and the direct accepted answer.
The content is written by members of the stackoverflow.com community.
It is licensed under cc-wiki