0

わかりました、これはトピックから外れているように聞こえるかもしれませんが、誰かが同様の経験をしたかどうか、そして彼らが問題/解決策を見つけたかどうかを知りたい.

申し訳ありませんが、この投稿は自己試行錯誤の報告のようになりました。誰も答えていないからです。質問の最後に問題解決のステータス更新を追加しました。

しばらくの間、問題は私のデータベース更新クエリにあるようです。

netbeans 7.3でPHP + MySQL Webサイトを開発しています。+XAMPP。すべてが正常に機能していました。いいえ、突然私のログイン フォーム(いくつかの $_SESSION 変数を保存してページにリダイレクトするとします)が機能しません

奇妙なことは、Netbeans + Xdebug でデバッグするとすべてうまくいくことです。セッション変数が設定され、ページが正しく転送されます。

質問: 誰かが同様の問題に直面しましたか? 何がうまくいかないのか誰にもわかりませんか?

xdebugを実行すると、システム内の何かが異なって設定されているとしか思えません。(しかし、正確に(?) 同じログインが数日前に正常に機能していました)。

私は多くのことを試しました(何時間も試しましたが、それらのほとんどは今では頭に浮かびません)。リモート サーバーでページを移動しようとしましたが、同じ動作が続きます。

(さらに情報が必要な場合は、お問い合わせください。編集します。)

誰かがアイデアを持っていることを願っています!

編集:私のphp-session変数と関係があると思います。Xdebug では、サイトは空の php-session 変数で開始されるため、通常と同じものを使用/取得することに気付きました (?)

コードはデータベースへのセッションを作成していますが、php-session 変数を設定する次のステップに進みません。( /* HERE IS THE PLACE */ とマークされた index.php の場所を確認してください。

わかった。これは削除されたコードです(単独ではなく、netbeans + xdebugで作業します):

index.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';
?>

login.html.php:

<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <p class="login-error"><?php if(isset($loginError)) { echo $loginError; } else { echo '&nbsp;'; } ?></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>

編集:エラーをさらに追跡しましたが、$_POST 変数を Xdebuging している間は問題ないようですが、スタンドアロンの PHP インタープリターは何らかの方法でそれらを失っています。

奇妙なことに、if(isset($_POST['action']) && $_POST['action'] == 'login') 内でデータベースへのセッションを作成し、php がそこに入っていないように見えますが、そのif句内のデータベースにセッションを挿入できます。

編集:これを非常に平和になるまでブレーキをかけると、実際の問題にはまだ影響しないはずの1つの大きな間違いを見つけるのに役立ちましたが、見つけるのがはるかに難しくなりました。

認証の最後に 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行を返します

4

1 に答える 1

0

わかった。問題が解決しました。誰かが何らかの形で同様の問題に遭遇した場合、ここに答えを残します。この問題を隠すために Xdebug が何をしたかはまだわかりません。

問題は、データベース セッション テーブルの last_used フィールドを更新してユーザーを認証しようとしたことです。クエリがそのフィールドを更新できる場合、セッションは有効である必要があると想定しました。したがって、影響を受けるSQL更新last_user行が1に等しいかどうかを確認すると、ユーザーのphp-session-idがセッションテーブルにあります。問題は、更新された"reference"値がフィールドに既にある場合、MySQL が影響を受ける 0 行を返すことです。そして、私の場合はもちろんそうです。セッションの last_update フィールドがログイン手順で作成されたばかりだからです。

しかし、問題の原因を見つけるのは非常に苦痛でした.Xdebugがそこで非常に奇妙なことをしていました.0行が更新クエリに影響を与えた後、影響を受ける行の数1に等しい。

Xdebug がこのように動作する理由がわかっている場合は、コメントしてください。

于 2013-08-05T01:41:49.203 に答える