PHP 从选择中返回 id

发布于 2024-12-10 03:04:30 字数 892 浏览 0 评论 0原文

一段简单的 PHP 代码:

#login.php

$_SESSION['valid_user_id'] = getUserId($username, $password);


#user_auth_fns.php

function getUserId($username, $password)
{
    $username = addslashes($username);
    $username = mysql_real_escape_string($username);
    $password = addslashes($password);
    $password = mysql_real_escape_string($password);

    $conn = db_connect();

    $result = $conn->query("select id from user where username='$username' and password= sha1('$password')");
    if (!$result) {
        throw new Exception('Could not retrieve your user id.');
    }
    if ($result->num_rows > 0) {
        return $result;
    } else {
        throw new Exception('Could not retrieve your user id.');
    }
}

“return $result”是错误的,但是我不知道应该放什么才能从某个用户返回 id。 PHP手册也没有提供答案。我知道这个函数有效,因为

用 return "test" 替换 return $result

会返回预期的正确值。

Simple piece of PHP code:

#login.php

$_SESSION['valid_user_id'] = getUserId($username, $password);


#user_auth_fns.php

function getUserId($username, $password)
{
    $username = addslashes($username);
    $username = mysql_real_escape_string($username);
    $password = addslashes($password);
    $password = mysql_real_escape_string($password);

    $conn = db_connect();

    $result = $conn->query("select id from user where username='$username' and password= sha1('$password')");
    if (!$result) {
        throw new Exception('Could not retrieve your user id.');
    }
    if ($result->num_rows > 0) {
        return $result;
    } else {
        throw new Exception('Could not retrieve your user id.');
    }
}

"return $result" is wrong, however I have no idea what I should put there in order to return the id from a certain user. The PHP manual didn't provide the answer either. I know this function works because replacing

return $result by return "test"

returns the correct value as expected.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

奈何桥上唱咆哮 2024-12-17 03:04:30
if ($result->num_rows > 0) { 
    $row = mysql_fetch_row($result);
    return $row['id'];
} else { 
    throw new Exception('Could not retrieve your user id.'); 
} 

我会像这样重写整个函数:

function getUserId($username, $password) 
{ 
    $username = mysql_real_escape_string($username); 
    $password = mysql_real_escape_string($password); 

    $conn = db_connect(); 

    $result = $conn->query("SELECT id FROM user 
                            WHERE username = '$username' 
                              AND password = sha2(CONCAT(user.salt,'$password'),512)"); 
    if (!$result) { 
        throw new Exception('Could not retrieve your user id.'); 
    } 
    if ($result->num_rows > 0) { 
        $row = mysql_fetch_row($result);
        return $row['id'];
    } else { 
        throw new Exception('Could not retrieve your user id.'); 
    } 
} 

为了防止 XSS
在从数据库中回显任何值之前,请对其进行清理:

echo htmlentities($row['username']);

确保对这些哈希值加盐,否则将不安全
请注意,您需要将一个名为 SALT 的新字段添加到您的用户表中。

ALTER TABLE user ADD COLUMN salt INTEGER NULL default NULL;

因为密码是经过哈希处理的,所以您需要时间来翻译它们,请使用以下代码插入新条目:

INSERT INTO user (username, salt, password) 
  SELECT '$username', @salt, SHA2(CONCAT(@salt,'$password'),512)
  FROM DUAL CROSS JOIN (SELECT @salt:= FLOOR(RAND()*99999999)) q;

此代码用于测试有效密码:

SELECT id, COALESCE(salt,-1) as salt FROM user 
  WHERE username = '$username' 
    AND CASE WHEN salt IS NULL 
             THEN password = SHA1('$password)
             ELSE password = SHA2(CONCAT(salt,'$password'),512) END;

当盐结果为 -1 时,像这样更新用户表。

 UPDATE user 
   CROSS JOIN (SELECT @salt:= FLOOR(RAND()*99999999)) q
 SET salt = @salt, password = SHA2(CONCAT(@salt,'$username'),512); 
if ($result->num_rows > 0) { 
    $row = mysql_fetch_row($result);
    return $row['id'];
} else { 
    throw new Exception('Could not retrieve your user id.'); 
} 

I would rewrite the whole function like so:

function getUserId($username, $password) 
{ 
    $username = mysql_real_escape_string($username); 
    $password = mysql_real_escape_string($password); 

    $conn = db_connect(); 

    $result = $conn->query("SELECT id FROM user 
                            WHERE username = '$username' 
                              AND password = sha2(CONCAT(user.salt,'$password'),512)"); 
    if (!$result) { 
        throw new Exception('Could not retrieve your user id.'); 
    } 
    if ($result->num_rows > 0) { 
        $row = mysql_fetch_row($result);
        return $row['id'];
    } else { 
        throw new Exception('Could not retrieve your user id.'); 
    } 
} 

To prevent XSS
Before echoing any value from a database sanitize it:

echo htmlentities($row['username']);

Make sure you salt those hashes, or you will not be secure
Note that you will need to add a new field called SALT to your user table.

ALTER TABLE user ADD COLUMN salt INTEGER NULL default NULL;

Because the passwords are hashed, you will need time to translate them, use the following code to insert new entries:

INSERT INTO user (username, salt, password) 
  SELECT '$username', @salt, SHA2(CONCAT(@salt,'$password'),512)
  FROM DUAL CROSS JOIN (SELECT @salt:= FLOOR(RAND()*99999999)) q;

And this code to test for valid passwords:

SELECT id, COALESCE(salt,-1) as salt FROM user 
  WHERE username = '$username' 
    AND CASE WHEN salt IS NULL 
             THEN password = SHA1('$password)
             ELSE password = SHA2(CONCAT(salt,'$password'),512) END;

Update the user table like so when salt turns out be be -1.

 UPDATE user 
   CROSS JOIN (SELECT @salt:= FLOOR(RAND()*99999999)) q
 SET salt = @salt, password = SHA2(CONCAT(@salt,'$username'),512); 
没有伤那来痛 2024-12-17 03:04:30

$result 仅包含结果行的对象。要访问数据,您需要从结果中获取行。

使用 mysqli 库:

$result = $conn->query("select id from user where username='$username' and password= sha1('$password')");
$row = $result->fetch_object(); // or $row = $result->fetch_array();
return $row->id;

使用使用数组的 mysql 库:

$result = $conn->query("select id from user where username='$username' and password= sha1('$password')");
$row = $result->fetch_assoc();
return $row['id'];

$result contains only the object of resulting rows. To access the data, you need to fetch the row from result.

With the mysqli library:

$result = $conn->query("select id from user where username='$username' and password= sha1('$password')");
$row = $result->fetch_object(); // or $row = $result->fetch_array();
return $row->id;

With the mysql library using array:

$result = $conn->query("select id from user where username='$username' and password= sha1('$password')");
$row = $result->fetch_assoc();
return $row['id'];
再见回来 2024-12-17 03:04:30

来自 php.net

// Use result
// Attempting to print $result won't allow access to information in the resource
// One of the mysql result functions must be used
// See also mysql_result(), mysql_fetch_array(), mysql_fetch_row(), etc.
while ($row = mysql_fetch_assoc($result)) {
    echo $row['firstname'];
    echo $row['lastname'];
    echo $row['address'];
    echo $row['age'];
}

From php.net:

// Use result
// Attempting to print $result won't allow access to information in the resource
// One of the mysql result functions must be used
// See also mysql_result(), mysql_fetch_array(), mysql_fetch_row(), etc.
while ($row = mysql_fetch_assoc($result)) {
    echo $row['firstname'];
    echo $row['lastname'];
    echo $row['address'];
    echo $row['age'];
}
×眷恋的温暖 2024-12-17 03:04:30

试试这个:

if ($result->num_rows > 0) {
    $tmp = $result->fetch_assoc();
    $return = $tmp['id'];
    return $return;
} else { ...

Try this:

if ($result->num_rows > 0) {
    $tmp = $result->fetch_assoc();
    $return = $tmp['id'];
    return $return;
} else { ...
动听の歌 2024-12-17 03:04:30

我不知道您正在使用什么数据库包装器,因为您还没有向我们展示 db_connect(),但我打赌这会起作用:

$result = $conn->query(...);
$result = $result->fetch();
return $result['id'];

$conn 返回的值是可能是代表结果资源的对象,而不是实际的行。您需要从资源中获取行,因为可能有多个行。

I don't know what DB wrapper you are using since you haven't shown us db_connect(), but I bet this will work:

$result = $conn->query(...);
$result = $result->fetch();
return $result['id'];

The value returned from $conn is probably an object representing a result resource, not actual rows. You need to fetch the rows from the resource as there are potentially more than one.

青春如此纠结 2024-12-17 03:04:30

在我看来,主要问题是你的函数返回结果对象,而你实际上只需要返回 id 字段。为此,您必须从结果对象中以对象/数组/关联数组的形式获取行,并从中返回 id 字段。只是为了说明我的想法,就本机 MySQL 函数而言,它看起来像这样:

$res = mysql_query("SELECT id FROM usersTable WHERE username = '".mysql_real_escape_string($userName) . "' AND password = '" .mysql_real_escape_string($password) ."' LIMIT 1") or die("Cannot select id: ".mysql_error());
if(mysql_num_rows($res) > 0) {
   $row = mysql_fetch_assoc($res); // fetch the retrived row as associative array, my personal favorite though others may prefer mysql_fetch_row or mysql_fetch_object instead
   return $row['id']; // return the retrived id 
}
else {
   // your exception throwing code goes here
}

作为旁注,看不到 mysql_real_escape_string 后面的addslashes有任何意义,因为它们基本上是为了做同样的事情,而 mysql_real_escape_string 是首选方式转义数据库查询中的用户输入。所以,我认为你应该只留下 mysql_real_escape_string 行并去掉addslashes 的东西。

In my opinion, the main problem is that your function is returning the result object, while you actually had to return only the id field. In order to do that you had to fetch the row from the result object as object / array / associative array and return the id field from it. Just to illustrate my idea, in terms of native MySQL functions it would look something like this:

$res = mysql_query("SELECT id FROM usersTable WHERE username = '".mysql_real_escape_string($userName) . "' AND password = '" .mysql_real_escape_string($password) ."' LIMIT 1") or die("Cannot select id: ".mysql_error());
if(mysql_num_rows($res) > 0) {
   $row = mysql_fetch_assoc($res); // fetch the retrived row as associative array, my personal favorite though others may prefer mysql_fetch_row or mysql_fetch_object instead
   return $row['id']; // return the retrived id 
}
else {
   // your exception throwing code goes here
}

As a side note, do not see any sense in addslashes followed by mysql_real_escape_string since they are basically meant to do the same thing and mysql_real_escape_string is the preferred way to escape user input in database queries. So, I think you should just leave mysql_real_escape_string lines and get rid of addslashes stuff.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文