草庐IT

PHP 登录脚本和 SQL 查询始终返回相同的用户 ID

coder 2023-10-21 原文

我发布了一个问题,寻求帮助解决我遇到的问题,该问题已关闭,因为它已本地化。我现在已经缩小了我的问题范围。

我问的原题可以看PHP Login Script Returning Same user id? .

我的登录脚本有问题。一切似乎都正常,我没有收到任何错误或任何错误。

基本上,当我登录时,从数据库中检索到的 user_uid(用户 uid)始终为 3,由于某种原因,它没有获得正确的 user_uid,但是所有存储在 session 中的其他详细信息是正确的。

导致问题的查询是这个

$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 ,一定与我从多个表中检索并且查询在某处搞砸了这一事实有关。

这是 SqlFiddle 的链接,其中包含我的架构和 SQL 查询 http://sqlfiddle.com/#!2/3cc32/1/0

下面是回显的值数组,出于某种原因,即使在以测试帐户 phploveruser_uid 假设为 6 strong>,它显示表中第一行的 user_uid '3',似乎在某处发生冲突。

经过进一步测试,它似乎从 users 表中获取了正确的数据,除了 user_uid,但它从 users_profiles 中检索信息,并且users_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] => 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();
?>

最佳答案

重写这个:

FROM users, users_profiles, users_roles

为此:

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

...否则您的查询会生成 CROSS JOIN (至少可以说,这是非常低效的)。

如果某些 users 记录在 users_profilesusers_roles 中可能没有对应的记录(对于这些用户相应的列值将在返回的行集中设置为 NULL)。

关于PHP 登录脚本和 SQL 查询始终返回相同的用户 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12951839/

有关PHP 登录脚本和 SQL 查询始终返回相同的用户 ID的更多相关文章

  1. ruby - ECONNRESET (Whois::ConnectionError) - 尝试在 Ruby 中查询 Whois 时出错 - 2

    我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.

  2. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  3. ruby-on-rails - 独立 ruby​​ 脚本的配置文件 - 2

    我有一个在Linux服务器上运行的ruby​​脚本。它不使用rails或任何东西。它基本上是一个命令行ruby​​脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg

  4. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  5. ruby-on-rails - 在 Rails 和 ActiveRecord 中查询时忽略某些字段 - 2

    我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr

  6. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

  7. ruby - RVM "ERROR: Unable to checkout branch ."单用户 - 2

    我在新的Debian6VirtualBoxVM上安装RVM时遇到问题。我已经安装了所有需要的包并使用下载了安装脚本(curl-shttps://rvm.beginrescueend.com/install/rvm)>rvm,但以单个用户身份运行时bashrvm我收到以下错误消息:ERROR:Unabletocheckoutbranch.安装在这里停止,并且(据我所知)没有安装RVM的任何文件。如果我以root身份运行脚本(对于多用户安装),我会收到另一条消息:Successfullycheckedoutbranch''安装程序继续并指示成功,但未添加.rvm目录,甚至在修改我的.bas

  8. postman——集合——执行集合——测试脚本——pm对象简单示例02 - 2

    //1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json

  9. Hive SQL 五大经典面试题 - 2

    目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类

  10. sql - 查询忽略时间戳日期的时间范围 - 2

    我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时

随机推荐