【问题标题】:Return a MySQLi query results from a function while using "Prepare Statment"使用“准备语句”时从函数返回 MySQLi 查询结果
【发布时间】:2015-08-08 16:35:37
【问题描述】:

这是我第一次使用prepare语句方法。

问题是函数返回 Nothing "null"。

功能:

function login($username, $password)
{

    $username = sanitize($username);
    $password = md5($password);

    global $connect;

    $stmt = $connect->prepare("SELECT `user_id` FROM `users` WHERE `username` = ? AND `password` = ? ");

    $stmt->bind_param("ss", $username, $password);
    $stmt->execute();

    $stmt->bind_result($id);
    $result = $stmt->fetch();

    $stmt->close();
    $connect->close();

    return $result;
} 

我得到的错误:

"mysqli_num_rows() 期望参数 1 为 mysqli_result,null 给出”

不知道是什么问题!


最新结果:

function login($username, $password)
{
    global $connect;

    $stmt = $connect->prepare("SELECT `user_id` FROM `users` WHERE `username` = ? AND `password` = ? ");
    $stmt->bind_param("ss", $username, $password);
    $stmt->execute();

    $result = $stmt->get_result();
    while ($row = $result->fetch_array(MYSQLI_NUM))
    {
        $result[] = $row;
    }

    $stmt->close();
    $connect->close();

    return $result;
} 

不能使用 mysqli_result 类型的对象作为“$result[] = $row;”中的数组

【问题讨论】:

  • 你能添加你的数据库连接类吗?
  • md5 用于密码哈希与根本不对其进行哈希一样不安全。

标签: php function mysqli null prepared-statement


【解决方案1】:

几乎每件事都可以,除了你不能像你那样从 fetch 语句中得到结果。

这一切都取决于您的登录功能将如何工作,您可以通过多种方式进行操作,我将演示 3 个示例并留给您:

对于这两种解决方案:
在您的 sql 语句中,您可以选择您想要的特定字段或所有字段:

SELECT `user_id`, `email`, `username`, `password` FROM `users`......etc...

或所有字段,如:

SELECT * FROM `users`......etc...

解决方案 1:
替换

$stmt->bind_result($id);
$result = $stmt->fetch();

有了这个

$output = $stmt->get_result();
while ($row = $output->fetch_array(MYSQLI_NUM))
{
    $result = $row;
}

并调用你的登录方法/函数,我注入了一个测试用户进行测试:

print_r(login("user", "1234"));

我从我的虚拟测试数据库中得到的结果,一个包含数据库表中关于特定用户的所有字段数据的数组,如下所示(我在SELECT 语句中使用了星号*):

Array ( [0] => 1 [1] => user@user.com [2] => user [3] => 1234 ) 

解决方案 2:
我们保留之前删除的 2 行,但添加将包含从数据库中获取的值的变量,它应该与 SELECT 语句中的顺序相同,如果您选择星号 (*) 那么您需要编写所有数据库顺序中的字段。我们的bind_result 语句将向我们提供数据库中的结果,如果您错过了一个字段,它将无法工作并返回错误。

替换

$stmt->bind_result($id);
$result = $stmt->fetch();

有了这个

$stmt->bind_result($db_user_id, $db_email, $db_username, $db_password);
$stmt->fetch();

如果你需要用户邮箱地址,那么使用$db_email变量,你可以将全部或部分结果放入数组中并返回它甚至返回单个值,这取决于你。

解决方案 3

这个方案结合了1和2。

替换

$stmt->bind_result($id);
$result = $stmt->fetch();

有了这个

$stmt->bind_result($db_user_id, $db_email, $db_username, $db_password);
while ($stmt->fetch()) {
    echo $db_user_id;
}

这里也一样,如果你需要用户邮箱地址,那么使用$db_email变量,你可以将全部或部分结果放入数组中并返回,甚至返回单个值。这取决于你。


注意:
为了减少测试失败的机会,我在测试时禁用了sanitize($username)md5($password)。所以我只使用纯文本,只是为了测试并查看一切是否按预期工作。工作完成后,您可以再次激活它们。 我建议您也使用另一种散列解决方案,因为 md5 被认为对密码不安全。请参阅Best Practices 的 PHP 手册页。

【讨论】:

  • 非常感谢,一切都是为了更好,但我按照你说的做了之后出现了这个错误。错误发生在 $result[] = $row;
  • 不能使用mysqli_result类型的对象作为数组
  • 您正在使用哪种解决方案?我已经编辑了我的答案,请再次检查。
  • 非常感谢您的努力。第三个就像一个魅力。我刚刚删除了“mysqli_num_rows”并将其替换为 !empty();再次感谢您。
  • 没问题,确实不客气,祝你好运。这一切都取决于要求是什么,添加 3 个示例可以找到最佳解决方案。
猜你喜欢
  • 2011-01-23
  • 1970-01-01
  • 2016-04-15
  • 1970-01-01
  • 1970-01-01
  • 2012-01-31
  • 1970-01-01
  • 2020-05-03
  • 1970-01-01
相关资源
最近更新 更多