2012-10-18 33 views
3

我發佈了一個問題,尋求幫助來解決我遇到的問題,因爲它本地化而被關閉。我現在已經縮小了我的問題。PHP登錄腳本和SQL查詢總是返回相同的用戶ID

我問的原始問題可以看到PHP Login Script Returning Same user id?

我的登錄腳本出現問題。一切似乎工作正常,我沒有得到任何錯誤或任何東西。

基本上當我登入user_uid(用戶UID)從數據庫中檢索總是3,由於某種原因,沒有得到正確的user_uid,但是所有存儲在會話中的其他細節正確。

導致該問題的查詢是這樣的一個

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

    LIMIT 1"); 

如果我刪除users_rolesusers_profiles從SQL查詢,並從剛剛用戶表它得到正確的只是檢索user_uid,必須與我從多個表中檢索到的事實有關,並且查詢在某處出現混亂。

這裏有一個鏈接我的模式和SQL查詢http://sqlfiddle.com/#!2/3cc32/1/0

下面以SqlFiddle是值的數組呼應的,由於某種原因,即使user_uid被假設是作爲測試登錄時賬戶phplover,它顯示user_uid'3'是表中的第一行,似乎在某處發生衝突。

後進一步測試它似乎從用戶得到正確的數據表除了user_uid,但它檢索從users_profilesusers_roles在數據庫中的第一行中的信息,也許是越來越來自用戶的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] => [email protected] 
    [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(); 
?> 
+0

因爲您的查詢返回多行並且因爲您限制顯示1行...它總是選擇'3'。你還沒有加入3個表 – WatsMyName

回答

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(至少可以說這是非常低效的)。

此時應更換INNER與LEFT OUTER JOIN JOIN這裏如果一些users記錄可能沒有相應的users_profilesusers_roles(這些用戶的相應的列值將在返回的行集設置爲NULL)的記錄。

+0

嗨,當用戶註冊和數據輸入到用戶表中的用戶配置文件和用戶角色行在users_profiles和users_roles表中創建,所以據我瞭解INNER JOIN會好嗎?感謝phplover – PHPLOVER

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"); 
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 
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') 
0

使用此查詢

「SELECT * FROM用戶,因爲您在u.user_uid = us.user_uid上留下了加入users_roles的用戶名留下的加入users_profiles u.user_uid = up.user_uid 其中u.user_login =:用戶名或u.user_email =:電子郵件LIMIT 1「

相關問題