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!
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.