3

私が抱えている問題を解決するための助けを求める質問を投稿しましたが、ローカライズされたため閉鎖されました。問題を絞り込みました。

私が尋ねた元の質問は、同じユーザーIDを返すPHPログインスクリプトを見ることができますか?。

ログインスクリプトに問題があります。すべてが正常に機能しているようです。エラーなどは発生しません。

基本的に、ログインすると、データベースから取得したuser_uid(users uid)は常に3ですが、何らかの理由で正しいuser_uidを取得できませんが、セッションに保存されている他のすべての詳細は正しいです。

問題を引き起こしているクエリはこれです

$stmt = $dbh->prepare("
     SELECT
         *
     FROM
         users, users_roles, users_profiles
     WHERE
         user_login = :username
     OR
         user_email = :email

     LIMIT 1");

SQLクエリからusers_rolesusers_profilesを削除し、 usersテーブルだけから取得すると、正しいuser_uidが取得されます。これは、複数のテーブルから取得していて、クエリがどこかで混乱しているという事実と関係があるはずです。

これが私のスキーマとSQLクエリを使用したSqlFiddleへのリンクですhttp://sqlfiddle.com/#!2/3cc32/1/0

以下はエコーアウトされた値の配列です。何らかの理由で、テストアカウントphploverとしてログインするときにuser_uid6であると想定されていても、テーブルの最初の行であるuser_uid'3 'がどこかで競合しているように見えます。

さらにテストした後、 user_uidを除くusersテーブルから正しいデータを取得しているようですが、データベースの最初の行のusers_profilesusers_rolesから情報を取得しています。おそらく、usersテーブルからuser_uidを正しく取得していますが、クエリはそれを上書きします。

クエリを実行したのはphpMyAdminですが、それでも同じことを実行します。これは間違いなくSQLクエリと関係があります。クエリを修正して、正しいuser_uidを取得するにはどうすればよいですか。

Array
(
    [user_uid] => 3 // should be 6, 3 is the user_uid of the first row in database, seems to just fetch first row :/
    [user_status] => 1 
    [user_login] => PhpLover
    [user_pass] => 5e79a29e6292e7690a6bf56484140114f1374933081d499b8cc5034685950a16668868cd0886d93f9bc634a5649a6037022a5ef62e9b5d13cda24619bbdf610b;507a7ea891f609.84619944
    [user_email] => smaple@sample.com
    [user_registered] => 2012-10-14 09:58:16
    [user_display_name] => 
    [user_failed_logins] => 0
    [id] => 3 // not sure where this is coming from  but should be 6 like user_uid
    [user_role] => subscriber
    [user_gender] => 
    [user_url] => 
    [user_msn] => 
    [user_aim] => 
    [user_yim] => 
    [user_twitter] => 
    [user_facebook] => 
)

これが私のログインスクリプトです。問題をSQLクエリに絞り込んだので表示する必要はありませんが、人々が何が起こっているのかをさらに理解するのに役立つ場合に備えて投稿すると思いました。

<?php
// ob_start()
ob_start();

// Include config.php
require_once("".$_SERVER['DOCUMENT_ROOT']."/de-admin/config.php");

// if user is logged in redirect them to control panel
// an already logged in user cannot login whilst already logged in!
alreadyloggedin();

// top.inc.php
require_once($top_inc);
?>

<!-- Meta start -->
<title><?php echo SITE_NAME; ?> - Member Login</title>
<meta name="description" content="<?php echo SITE_NAME; ?> - Member Login, Sign in" />
<meta name="keywords" content="sign up, member, login, signin, account, membership, <?php echo SITE_NAME; ?>" />
<!-- Meta end -->

<?php
// sidebar.inc.php
require_once($sidebar_inc);

// main.inc.php
require_once($main_inc);
?>

<?php

    if(isset($_POST['username_email'], $_POST['password'], $_POST[BOT_TEST], $_POST['token'])){

        // check if form token is valid
        IsValidFormTokenHash();

        // initialize form errors array
        $error    = array();

        // fetch form data
        $username_email = trim($_POST['username_email']);
        $password       = trim($_POST['password']);
        $bottest        = $_POST[BOT_TEST];

        // validate form data
        if(empty($username_email)){
            $error[] = 'Please enter your username or email address';
        }
        if(empty($password)){
            $error[] = 'Please enter your password';
        }
        if(!empty($bottest)){
            $error[] = 'Spambot detected, if your human please try again';
        }
        if(!empty($username_email) && !empty($password)){
            try{

                // connect to database
                $dbh = sql_con();

                // prepare query
                $stmt = $dbh->prepare("
                            SELECT
                                *
                            FROM
                                users, users_roles, users_profiles
                            WHERE
                                users.user_login = :username
                            OR
                                users.user_email = :email
                            AND
                                users.user_uid = users_roles.user_uid
                            AND
                                users.user_uid = users_profiles.user_uid
                            LIMIT 1");

                // execute query
                $stmt->execute(array(':username' => $username_email, ':email' => $username_email));

                if ($stmt->rowCount() > 0) {

                    $result = $stmt->fetch(PDO::FETCH_ASSOC);
                    echo '<pre>';
                    print_r($result);
                    echo '</pre>';
                    $user_db_pass = $result['user_pass'];

                    if(!ValidatePassword($password, $user_db_pass)){
                        $error[] = 'Invalid Login Details';
                    } else {

                        $user_status = $result['user_status'];

                        if($user_status == USER_STATUS_VERIFY){
                            $error[] = 'You must verify your account before you can log in';
                        }elseif($user_status == USER_STATUS_SUSPENDED){
                            $error[] = 'This account has been suspended';
                        }elseif($user_status == USER_STATUS_SPAM){
                            $error[] = 'This account has been marked as potentially spam';
                        } else {

                            // user valid

                            // fetch user details and assign there details to there sessions
                            $_SESSION['user_uid']          = $result['user_uid'];
                            $_SESSION['user_status']       = $result['user_status'];
                            $_SESSION['user_login']        = $result['user_login'];
                            $_SESSION['user_email']        = $result['user_email'];
                            $_SESSION['user_registered']   = $result['user_registered'];
                            $_SESSION['user_display_name'] = $result['user_display_name'];
                            $_SESSION['user_role']         = $result['user_role'];
                            $_SESSION['user_gender']       = $result['user_gender'];
                            $_SESSION['user_url']          = $result['user_url'];
                            $_SESSION['user_msn']          = $result['user_msn'];
                            $_SESSION['user_aim']          = $result['user_aim'];
                            $_SESSION['user_yim']          = $result['user_yim'];
                            $_SESSION['user_twitter']      = $result['user_twitter'];
                            $_SESSION['user_facebook']     = $result['user_facebook'];

                            // unset (destroy) form token
                            UnsetFormToken();

                            // On successful login get URI user was on
                            // so we can redirect them back to URI they was on
                            /*if(isset($_SESSION['redirect_to'])){
                                // if session redirect_to is found this means
                                // they tried to access a membersarea()
                                // so we get the URI and redirect to the
                                // secure page they tried accessing before logged in
                                $redirect_to = $_SESSION['redirect_to'];
                                // unset the session var
                                unset($_SESSION['redirect_to']);
                                // redirect
                                header("Location: ".SITE_URL."$redirect_to");
                                exit();
                            } else {
                                header("Location: /member/control-panel");
                                exit();
                            }*/

                            // now logged in redirect to control panel
                            //header("Location: /member/control-panel");
                            exit;
                        }
                    }

                } else {
                    $error[] = 'Incorrect login details';
                }

                // close database connection
                $dbh = null;

            }
            catch (PDOException $e){
                ExceptionErrorHandler($e);
                require_once($footer_inc);
                exit;
            }
        }

        // If errors found display errors
        if(!empty($error)){
            $SiteErrorMessages = '';
            foreach($error as $msg){
                $SiteErrorMessages .= "$msg <br />";
            }
        }
    }


    // display error messages
    if(isset($SiteErrorMessages)){
        SiteErrorMessages();
    }

    // the below values is to replace placeholders in tpl
    $TemplateReplacementValues = array(
        'SITE_NAME'         => SITE_NAME,
        'FORM_TOKEN_HASH'   => GenerateFormTokenHash(),
        'BOT_TEST'          => BotTest()
    );

    // signup.tpl template location
    $tpl = DOCUMENT_ROOT.'inc/tpl/login.tpl';

    // load signup template
    PageContentTemplate($tpl, $TemplateReplacementValues);

?>

<?php
// footer.inc.php
require_once($footer_inc);

// ob_end-flush
ob_end_flush();
?>
4

5 に答える 5

3

これを書き直してください:

FROM users, users_profiles, users_roles

これに:

FROM users
INNER JOIN users_profiles USING (user_uid)
INNER JOIN users_roles USING (user_uid)

... そうしないと、クエリでCROSS JOINが生成されます(控えめに言っても、これは非常に非効率的です)。

一部のレコードがandusersに対応するレコードを持たない可能性がある場合は、ここで INNER JOIN を LEFT OUTER JOIN に置き換える必要があります (これらのユーザーの場合、返される行セットで対応する列の値が NULL に設定されます)。users_profilesusers_roles

于 2012-10-18T09:55:23.297 に答える
0

試す

SELECT users.*,users_roles.*,users_profiles.* FROM  users
LEFT OUTER JOIN user_roles ON users.user_uid=users_roles.user_uid
LEFT OUTER JOIN  users_profiles ON  users.user_uid = users_profiles.user_uid 
WHERE users.user_login = :username OR users.user_email = :email LIMIT 1
于 2012-10-18T09:58:59.583 に答える
0

2 つ以上のテーブルを結合しようとしています。フィドル内での動作は次のとおりです。

SELECT *
FROM users 
INNER JOIN users_roles ON users.user_uid=users_roles.user_uid
INNER JOIN users_profiles ON users.user_uid = users_profiles.user_uid
WHERE (users.user_uid=6) AND (users.user_login='phplover')
于 2012-10-18T10:08:45.297 に答える
0
$stmt = $dbh->prepare("
     SELECT
         *
     FROM
         users, users_roles, users_profiles
     WHERE
         (user_login = :username OR user_email = :email)
         AND users.user_uid = users_roles.user_uid
         AND users.user_uid = users_profiles.user_uid

     LIMIT 1");
于 2012-10-18T09:56:08.593 に答える
0

このクエリを使用

「SELECT * FROM users as u left join users_roles as us on u.user_uid = us.user_uid left Join users_profiles as up u.user_uid = up.user_uid WHERE u.user_login= :username OR u.user_email =:email LIMIT 1」

于 2012-10-18T10:10:07.203 に答える