Привет
У меня возникли проблемы со страницей PHP: я пишу небольшую CMS, используя этот учебник.
Мне удается написать класс, который я использую для взаимодействия с меню, и все работает хорошо: я могу вставлять, удалять и получать все элементы меню на странице, где я могу изменить их порядок.
Когда я начал писать ту же страницу для пользователей, я столкнулся с проблемой: я использую класс Sentry для проверки пользователей на каждой странице:
require_once('../includes/Sentry.php');
$theSentry = new Sentry();
if (!$theSentry->checkLogin(1) ){ header("Location: index.php"); die(); }
Теперь: если я использую только эту проверку, страница работает хорошо, но мне нужно запросить базу данных и извлечь всех пользователей на странице 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 " ... " };
Если я прокомментирую один из двух разделов, все работает хорошо, но если я оставлю этот код работающим вместе, страница будет создана правильно, но в следующий раз, когда я запусту страницу, используя класс 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;
}
}
}
}
И это функция для получения пользователей:
class DbUser extends DbConnector{
...
function getUserArray() {
while ($row = mysql_fetch_object($this->user_result)) {
$this->users[$row->id] = $row;
}
return $this->users;
}
}
Я знаю, что это сложный для объяснения вопрос, поэтому дайте мне знать, если мне нужно указать что-то еще ...
Спасибо
РЕДАКТИРОВАТЬ: Ошибка в классе 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;
}
}
БОЛЬШИЕ НОВОСТИ: я нашел, где была ошибка, но я не могу понять, почему этот код не работает:
$user_connector = new DbUser();
$all_users = array();
$all_users = $user_connector->getUsers();
foreach($all_users as $id => $user){ ... }
Оператор foreach - это точка: когда я использую $all_user
как $id=>$user
, он фактически перезаписывает содержимое $ _SESSION ['user'] последним объектом, использованным в цикле (объект "user" ). Кто-нибудь может объяснить мне, как локальная переменная может перезаписать сеанс?
Я хотел бы прояснить: я решаю проблему (меняя $id => $user
на $id => $userObj
), но я ищу объяснение.
Спасибо!