Php 从查询结果设置会话变量

Php 从查询结果设置会话变量,php,mysql,Php,Mysql,我一直在修改一个用户身份验证系统,但在为管理员设置会话时遇到了问题。reguser会话的设置很好,但我不明白为什么admin不会设置 userlevel为9的用户是管理员。是的,我知道如何防止SQL注入。我现在只是想让它保持简单易读。这可能不会用于任何事情,我只是获得了一些PHP的经验 大家好,谢谢你们的帮助!我让它工作了。我盯着它看了太久,脑子都不清楚了。昨天休息了一会儿,今天又回来了,在不到5分钟的时间里就搞定了!你们太棒了,我爱你们 function checklogin($email,

我一直在修改一个用户身份验证系统,但在为管理员设置会话时遇到了问题。
reguser
会话的设置很好,但我不明白为什么
admin
不会设置

userlevel
为9的用户是管理员。是的,我知道如何防止SQL注入。我现在只是想让它保持简单易读。这可能不会用于任何事情,我只是获得了一些PHP的经验

大家好,谢谢你们的帮助!我让它工作了。我盯着它看了太久,脑子都不清楚了。昨天休息了一会儿,今天又回来了,在不到5分钟的时间里就搞定了!你们太棒了,我爱你们

function checklogin($email, $pass) {
        $server = 'localhost';
        $user = 'root';
        $password = '';
        $connection = mysql_connect($server, $user, $password) or die(mysql_error());
        mysql_select_db(udogoo, $connection) or die(mysql_error());
        $pass = md5($pass);
        $result = mysql_query("SELECT userid from users WHERE email = '$email' AND password = '$pass'");
        $user_data = mysql_fetch_array($result);
        $no_rows = mysql_num_rows($result);
        if ($no_rows == 1) 
    {
        $_SESSION['reguser'] = true;
        $_SESSION['userid'] = $user_data['userid'];
        $userid = $user_data['userid'];
        $isadmin = mysql_query("SELECT userlevel FROM users WHERE userid = '$userid'");
        $isadmin2 =  mysql_fetch_array($isadmin);
        $isadmin3 = $isadmin2['userlevel'];
        if ($isadmin3 == "9"){
        $_SESSION['admin'] = true;
        return true;
    }
    }
        else
    {
        return FALSE;
    }
}
因此,您的完整代码如下所示:

<?php
function checklogin($email, $pass) 
{
        $server = 'localhost';
        $user = 'root';
        $password = '';
        $connection = mysql_connect($server, $user, $password) or     die(mysql_error());
        mysql_select_db(test, $connection) or die(mysql_error());
        $pass = md5($pass);
        $result = mysql_query("SELECT userid from users WHERE email = '$email'  AND password = '$pass'");
        $user_data = mysql_fetch_array($result);
        $numrows = mysql_num_rows($result);
        if ($numrows == 1) 
        {
            $_SESSION['reguser'] = true;
            $_SESSION['userid'] = $user_data['userid'];

            //MY ANSWER START HERE
            $userid = $_SESSION['userid']; 
            $isadmin = mysql_query("SELECT userlevel FROM users WHERE userid = $userid");

            $user_data = mysql_fetch_array($result);
            $userlevel = $user_data['userlevel'];

            if($userlevel == '9')
            {
              $_SESSION['admin'] = true;
            }
            //END HERE 

        }
        else
        {
            return false;
        }
}

?>

您有一个
返回true如果用户数据存在。事实上,只有当用户不存在时,才能检查或管理属性


删除
返回true的选项,因为那里不需要它。如果需要,添加
否则返回false
检查用户是否存在后,
返回true就在末尾。

您的逻辑也有缺陷,如下所示:

function checklogin($email, $pass) 
{
    $server = 'localhost';
    $user = 'root';
    $password = '';
    $connection = mysql_connect($server, $user, $password) or die(mysql_error());
    mysql_select_db(test, $connection) or die(mysql_error());

    $email = mysql_real_escape_string($email);
    $pass = md5($pass);

    $sql = "SELECT `userid`,`userlevel` 
            FROM `users` 
            WHERE `email` = '$email' 
            AND `password` = '$pass' 
            LIMIT 1";  //I certainly hope you check email for injection before passing it here.  Also want the LIMIT 1 on there because you are only expecting a single return, and you should only get one since `email` should be unique since you're using it as a credential, and this will stop it from looking through all the rows for another match once it finds the one that matches.

    $result = mysql_query($sql);

    $user_data = mysql_fetch_array($result);
    $numrows = mysql_num_rows($result);

    if ($numrows == 1) 
    {
        $_SESSION['reguser'] = true;
        $_SESSION['userid'] = $user_data['userid'];

        if($user_data['userlevel'] == 9)
        {
            $_SESSION['admin'] = true;
        }
        else
        {
            $_SESSION['admin'] = false;
        }
        return true;
    }
    return false;
}
这应该行得通。当一个查询可以很好地完成时,没有很好的理由进行两个查询。如果用户已登录,则返回true;如果用户不存在或凭据不匹配,则返回false

Oops,SQL语句中的小语法错误,已更正。更大的语法错误也被纠正了

以下是您如何在PDO中完成顶部部分:

function checklogin($email, $pass) 
{
    $server = 'localhost';
    $user = 'root';
    $password = '';
    $dbname = 'test';
    $dsn = 'mysql:dbname=' . $dbname . ';host=' . $server;

    $conn = new PDO($dsn,$user,$password);  //Establish connection   

    $pass = md5($pass);

    $sql = "SELECT `userid`,`userlevel` 
            FROM `users` 
            WHERE `email` = :email 
            AND `password` = :pass 
            LIMIT 1";

    $stmt = $conn->prepare($sql);
    $stmt->bindParam(':email',$email,PDO::PARAM_STR,128)  //First param gives the placeholder from the query, second is the variable to bind into that place holder, third gives data type, fourth is max length
    $stmt->bindParam(':pass',$pass,PDO::PARAM_STR,32)  //MD5s should always have a length of 32

    $stmt->setFetchMode(PDO::FETCH_ASSOC);
    $stmt->execute();  //almost equivalent to mysql_query
    $user_data = $stmt->fetch();  //Grab the data

    if(is_array($user_data) && count($user_data) == 2)  //Check that returned info is an array and that we have both `userid` and `userlevel`
    {
        //Continue onwards

我以前也尝试过类似的方法,但没有效果。奇怪的是,它与“reguser”会话的设置方式几乎完全相同。
用户id
可能是字母数字字段,因此可能需要是
“$userid”
。但这似乎解决了使用
$result
进行搜索的明显错误。@JaredFarrish,谢谢你纠正我的答案。是的,你是对的。只是一个旁白,但是如果
$\u SESSION['userid']
设置正确,你可以使用它而不是函数范围的变量……不过,请注意@Kolink的回答,它讨论了函数在到达有效用户之前短路的事实。
返回TRUE
也需要显示出来。首先,
$result
是一个,因此您在
选择用户级别中包含它…
实际上并不是按照您认为的
用户ID进行搜索。它可能在搜索
资源ID 35; XX
或其他东西。与其使用普通的
md5()
值作为密码,不如使用
CRYPT\u BLOWFISH
散列类型和salt值,这使得存储密码更加安全。是的,这是另一个问题。好主意。你可以演示如何逃逸电子邮件地址(尽管OP确实提到了在电子邮件中逃逸)。注意,转义只是一种良好的实践,不一定是一种安全实践。事实上,由于这是一封电子邮件,只需检查它的有效电子邮件格式就足够了。想不到任何SQL注入都适合这种格式xxx@xxx.xxx或xxx@xxx.xx.xx. 对我来说,我只是确保我的输入符合他们的要求,并使用PDO和准备好的语句和绑定参数,不再担心它。这是一些不同寻常的建议。由于示例和您的答案不使用PDO,因此转义是一个事实要求。尽管进行了验证,但在大多数情况下查询中的输入都应该转义。我刚刚意识到:用户在查询中缺少
。@Jared Farrish修复了用户的
。他没有使用PDO,所以我没有在PDO中使用它,所以我注意到它应该被转义。当使用准备好的语句和绑定参数时,PDO将转义输入并检查其数据类型的有效性。如果他的问题是“如何转义mysql_查询输入”,那么我将讨论如何转义它。
function checklogin($email, $pass) 
{
    $server = 'localhost';
    $user = 'root';
    $password = '';
    $dbname = 'test';
    $dsn = 'mysql:dbname=' . $dbname . ';host=' . $server;

    $conn = new PDO($dsn,$user,$password);  //Establish connection   

    $pass = md5($pass);

    $sql = "SELECT `userid`,`userlevel` 
            FROM `users` 
            WHERE `email` = :email 
            AND `password` = :pass 
            LIMIT 1";

    $stmt = $conn->prepare($sql);
    $stmt->bindParam(':email',$email,PDO::PARAM_STR,128)  //First param gives the placeholder from the query, second is the variable to bind into that place holder, third gives data type, fourth is max length
    $stmt->bindParam(':pass',$pass,PDO::PARAM_STR,32)  //MD5s should always have a length of 32

    $stmt->setFetchMode(PDO::FETCH_ASSOC);
    $stmt->execute();  //almost equivalent to mysql_query
    $user_data = $stmt->fetch();  //Grab the data

    if(is_array($user_data) && count($user_data) == 2)  //Check that returned info is an array and that we have both `userid` and `userlevel`
    {
        //Continue onwards