好的,这听起来可能离题,但我想知道是否有人有类似的经历,以及他们是否找到了问题/解决方案。
抱歉,这篇文章更像是自我尝试和错误报告,因为没有人回答。我在问题底部添加了问题解决的状态更新。
有一段时间,问题似乎是我的数据库更新查询。
我正在 netbeans 7.3 上开发 PHP+MySQL 网站。+ XAMPP。一切正常。没有突然我的登录表单(假设保存一些 $_SESSION 变量并重定向到页面)不起作用。
奇怪的是,当我使用 Netbeans + Xdebug 进行调试时一切正常。会话变量已正确设置和页面转发。
问题:有人遇到过类似的问题吗?有谁知道可能出了什么问题?
我只能假设运行 xdebug 时系统中的某些内容设置不同。(但是几天前确切的(?)相同的登录工作正常)。
我已经尝试了很多事情(很多很多小时,但现在大多数都没有想到)。我试图在远程服务器上移动页面并且相同的行为继续。
(如果您想了解更多信息,请询问,我将进行编辑。)
希望有人有想法!
编辑:我认为与我的 php-session 变量有关。我意识到,虽然 Xdebug 站点以空的 php-session 变量开始,但它确实使用/获取与它通常具有的相同的变量(?)
该代码正在创建数据库会话,但没有进入下一步设置 php-session 变量。(查看 index.php 中标记为 /* HERE IS THE PLACE */
好的。这是剥离的代码(与 netbeans+xdebug 一起工作,而不是单独使用):
索引.php:
<?php
//Open PDO connection to MySQL server: $db_con
$db_connection = $_SERVER['DOCUMENT_ROOT'] . '/test-login/db.php';
require $db_connection;
session_start();
//******************************************************************************
//Helping functions
function convert_time_to_utc_date ($UNIX_timestamp) {
return gmdate("Y-m-d H:i:s", $UNIX_timestamp);
}
//******************************************************************************
// Function to authenticate user with username and password. returns FALSE if not authenticated and TRUE if successful authentication
function authenticate_username_password($db_con, $usernm, $passwd)
{
try {
$stmt = $db_con->prepare("SELECT id, hashed_pwd, COUNT(*) AS usercount FROM gui_users WHERE username=? AND not_in_use = 0 AND deleted = 0");
$stmt->execute(array($usernm));
if($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
if($row['usercount'] == 1){
if(crypt($passwd, $row['hashed_pwd']) == $row['hashed_pwd']){
$user_id = $row['id'];
session_regenerate_id(true);
$new_session_id = session_id();
$remote = true;
$datenow = convert_time_to_utc_date(time());
$stmt = $db_con->prepare("INSERT INTO gui_sessions (session_id,user_id,starttime_UTC,lastused_UTC,remote) VALUES (?, ?, ?, ?, ?)");
$stmt->execute(array($new_session_id, $user_id, $datenow, $datenow, $remote));
return $user_id;
}
}
}
return FALSE;
} catch (PDOException $e) {
return FALSE;
}
}
//******************************************************************************
//Function to get user roles
function get_user_roles(PDO $db_con, $user_id)
{
try {
$stmt = $db_con->prepare("SELECT role_id, role_last FROM gui_users WHERE id = ?");
$stmt->execute(array($user_id));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
return array('max_role_id' => $row['role_id'], 'last_role_id' => $row['role_last']);
} catch (PDOException $e) {
return FALSE;
}
}
//******************************************************************************
// Function to handel sessions, log in and log out
function authenticate(PDO $db_con) {
//********************
// If action is LOG IN
if (isset($_POST['action']) and $_POST['action'] == 'login') {
if (!isset($_POST['username']) or $_POST['username'] == '' or !isset($_POST['passwd']) or $_POST['passwd'] == '') {
$GLOBALS['loginError'] = 'Please fill in both fields';
return FALSE;
}
$user_id = authenticate_username_password($db_con, $_POST['username'], $_POST['passwd']);
if ($user_id !== false && $user_id > 0) {
$_SESSION['reloadcounter'] = 1;
$_SESSION['username'] = $_POST['username'];
$_SESSION['user_id'] = $user_id;
$_SESSION['user_def_page'] = 1; //get_user_default_page($db_con, $user_id);
$user_roles = get_user_roles($db_con, $user_id);
$_SESSION['max_role_id'] = $user_roles['max_role_id'];
$_SESSION['sel_role_id'] = $user_roles['last_role_id'];
$goto = isset($_POST['goto']) ? $_POST['goto'] : HTTPS_SERVER;
header('Location: ' . $goto);
exit;
} else {
$GLOBALS['loginError'] = 'Wrong username or password!';
return FALSE;
}
}
//*********************
// If action is LOG OUT
if (isset($_POST['action']) and $_POST['action'] == 'logout') {
$user_ses_id = session_id();
try {
$stmt = $db_con->prepare("DELETE FROM gui_sessions WHERE session_id=?");
$stmt->execute(array($user_ses_id));
} catch (PDOException $e) {
log_error('PDO_CONN', $e->getCode(), $e->getMessage(), TRUE, $db_con);
}
session_regenerate_id(true);
unset($_SESSION['reloadcounter']);
unset($_SESSION['username']);
unset($_SESSION['user_id']);
unset($_SESSION['user_def_page']);
unset($_SESSION['max_role_id']);
unset($_SESSION['sel_role_id']);
$goto = isset($_POST['goto']) ? $_POST['goto'] : HTTPS_SERVER;
header('Location: ' . $goto);
exit;
}
//************************************
// If no action see if user logged in
$user_ses_id = session_id();
$datenow = convert_time_to_utc_date(time());
try {
$stmt = $db_con->prepare("UPDATE gui_sessions SET lastused_UTC=? WHERE session_id=?");
$stmt->execute(array($datenow, $user_ses_id));
if ($stmt->rowCount() == 1) {
return TRUE;
} else {
unset($_SESSION['reloadcounter']);
unset($_SESSION['username']);
unset($_SESSION['user_id']);
unset($_SESSION['user_def_page']);
unset($_SESSION['max_role_id']);
unset($_SESSION['sel_role_id']);
return FALSE;
}
} catch (PDOException $e) {
log_error('PDO_CONN', $e->getCode(), $e->getMessage(), TRUE, $db_con);
if (DEBUG_ON) {
echo 'SESSION UPDATE FAILED<br>';
}
return FALSE;
}
}
//******************************************************************************
//SESSION CONTROL
if (!authenticate($db_con)) {
include 'login.html.php';
exit();
}
include 'page.html.php';
?>
登录.html.php:
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<p class="login-error"><?php if(isset($loginError)) { echo $loginError; } else { echo ' '; } ?></p>
<form id="login" action="" method="POST" name="login">
<label for="username">Username:</label><br />
<input name="username" type="text" size="40" value="" tabindex="0" /><br />
<label for="passwd">Password:</label><br />
<input name="passwd" type="password" size="40" value="" tabindex="1" /><br />
<input type="hidden" name="goto" value="https://localhost/test-login/"/>
<input type="hidden" name="action" value="login"/>
<input type="submit" class="button login" value="Login" tabindex="2"/><br />
</form>
<div><?php echo '<pre>' . var_dump($_SESSION) . '</pre>'; ?></div>
</body>
</html>
page.html.php:
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div>
<h1>Hello world!</h1>
<?php echo '<pre>' . var_dump($_SESSION) . '</pre>'; ?>
</div>
</body>
</html>
编辑:我已经更多地跟踪错误,似乎虽然 Xdebuging $_POST 变量没问题,但独立的 PHP 解释器正在失去它们。
奇怪的是,我在 if(isset($_POST['action']) && $_POST['action'] == 'login') 内部创建了与数据库的会话,并且 php 似乎没有进入那里,但它是能够在该 if 子句内的数据库中插入会话。
编辑:直到非常平静为止,这帮助我发现了一个大错误,该错误仍然不应该影响实际问题,但使它更难被发现。
因为我忘记在验证结束时在 if-else 中添加大括号,所以该函数总是取消设置会话变量。一开始我认为该函数无法设置它们,但实际上在重定向到“$_SERVER ['PHP_SELF']”后取消设置它们。无论如何,如果 UPDATE gui_session 语句有效,则不会发生这种情况。但这使得找出问题所在变得更加困难。这是 index.php 的更正:
//************************************
// If no action see if user logged in
$user_ses_id = session_id();
$datenow = convert_time_to_utc_date(time());
try {
$stmt = $db_con->prepare("UPDATE gui_sessions SET lastused_UTC=? WHERE session_id=?");
$stmt->execute(array($datenow, $user_ses_id));
if ($stmt->rowCount() == 1) {
return TRUE;
} else {
unset($_SESSION['reloadcounter']);
unset($_SESSION['username']);
unset($_SESSION['user_id']);
unset($_SESSION['user_def_page']);
unset($_SESSION['max_role_id']);
unset($_SESSION['sel_role_id']);
return FALSE;
}
} catch (PDOException $e) {
log_error('PDO_CONN', $e->getCode(), $e->getMessage(), TRUE, $db_con);
if (DEBUG_ON) {
echo 'SESSION UPDATE FAILED<br>';
}
return FALSE;
}
问题是此更新失败。但我不知道为什么。
$stmt = $db_con->prepare("UPDATE gui_sessions SET lastused_UTC=? WHERE session_id=?");
$stmt->execute(array($datenow, $user_ses_id));
if ($stmt->rowCount() == 1) {
return TRUE;
}
如果我在 php myadmin 中尝试:
UPDATE gui_sessions
SET lastused_UTC='2013-08-04 12:00:00'
WHERE session_id='03dfgpiu1jl8idcjf191hqv4m2'
它影响 0 行,但如果我这样做:
SELECT *
FROM gui_sessions
WHERE session_id='03dfgpiu1jl8idcjf191hqv4m2'
它返回 1 行