Return 在使用 "Prepare Statment" 时从一个函数得到一个 MySQLi 查询结果
Return a MySQLi query results from a function while using "Prepare Statment"
第一次使用prepare statement方式
问题是函数 return 没有 "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() expects parameter 1 to be mysqli_result, null
given in"
不知道是什么问题!
最新结果:
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;
}
Cannot use object of type mysqli_result as array in " $result[] = $row;"
几乎所有的事情都没有问题,除了你不能像你那样从 fetch 语句中得到结果。
一切都取决于您的登录功能如何工作,您可以通过多种方式实现,我将演示 3 个示例并留给您:
对于两种解决方案:
在您的 sql 语句中,您可以 select 您想要的特定字段或所有字段:
SELECT `user_id`, `email`, `username`, `password` FROM `users`......etc...
或所有字段如:
SELECT * FROM `users`......etc...
解决方案一:
替换
$stmt->bind_result($id);
$result = $stmt->fetch();
有了这个
$output = $stmt->get_result();
while ($row = $output->fetch_array(MYSQLI_NUM))
{
$result = $row;
}
并调用你的登录名method/function,我注入了一个测试用户进行测试:
print_r(login("user", "1234"));
我从我的虚拟测试数据库中得到的结果,一个数组,其中包含数据库 table 中关于特定用户的所有字段数据,如下所示(我在我的 SELECT
语句中使用了星号 *):
Array ( [0] => 1 [1] => user@user.com [2] => user [3] => 1234 )
方案二:
我们保留之前删除的 2 行,但添加将包含从数据库中获取的值的变量,它的顺序应与 SELECT
语句中的顺序相同,如果您选择星号 (*),则需要按数据库顺序写入所有字段。我们的 bind_result
语句将向我们提供来自数据库的结果,如果您错过一个字段,它将无法工作并且 return 错误。
替换
$stmt->bind_result($id);
$result = $stmt->fetch();
有了这个
$stmt->bind_result($db_user_id, $db_email, $db_username, $db_password);
$stmt->fetch();
如果你需要用户邮箱地址,那么使用$db_email
变量,你可以将全部或部分结果放在数组中,return它甚至return单个值,它是给你。
解决方案 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
变量,可以把全部或者部分结果放在数组中,return甚至return一个单一价值。由你决定。
注:
为了减少测试失败的机会,我在测试时禁用了 sanitize($username)
和 md5($password)
。所以我只使用纯文本,只是为了测试并查看是否一切都按预期工作。工作完成后,您可以再次激活它们。
我还建议您使用另一种哈希解决方案,因为 md5 被认为对密码不安全。请参阅 Best Practices 的 PHP 手册页。
第一次使用prepare statement方式
问题是函数 return 没有 "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() expects parameter 1 to be mysqli_result, null given in"
不知道是什么问题!
最新结果:
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;
}
Cannot use object of type mysqli_result as array in " $result[] = $row;"
几乎所有的事情都没有问题,除了你不能像你那样从 fetch 语句中得到结果。
一切都取决于您的登录功能如何工作,您可以通过多种方式实现,我将演示 3 个示例并留给您:
对于两种解决方案:
在您的 sql 语句中,您可以 select 您想要的特定字段或所有字段:
SELECT `user_id`, `email`, `username`, `password` FROM `users`......etc...
或所有字段如:
SELECT * FROM `users`......etc...
解决方案一:
替换
$stmt->bind_result($id);
$result = $stmt->fetch();
有了这个
$output = $stmt->get_result();
while ($row = $output->fetch_array(MYSQLI_NUM))
{
$result = $row;
}
并调用你的登录名method/function,我注入了一个测试用户进行测试:
print_r(login("user", "1234"));
我从我的虚拟测试数据库中得到的结果,一个数组,其中包含数据库 table 中关于特定用户的所有字段数据,如下所示(我在我的 SELECT
语句中使用了星号 *):
Array ( [0] => 1 [1] => user@user.com [2] => user [3] => 1234 )
方案二:
我们保留之前删除的 2 行,但添加将包含从数据库中获取的值的变量,它的顺序应与 SELECT
语句中的顺序相同,如果您选择星号 (*),则需要按数据库顺序写入所有字段。我们的 bind_result
语句将向我们提供来自数据库的结果,如果您错过一个字段,它将无法工作并且 return 错误。
替换
$stmt->bind_result($id);
$result = $stmt->fetch();
有了这个
$stmt->bind_result($db_user_id, $db_email, $db_username, $db_password);
$stmt->fetch();
如果你需要用户邮箱地址,那么使用$db_email
变量,你可以将全部或部分结果放在数组中,return它甚至return单个值,它是给你。
解决方案 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
变量,可以把全部或者部分结果放在数组中,return甚至return一个单一价值。由你决定。
注:
为了减少测试失败的机会,我在测试时禁用了 sanitize($username)
和 md5($password)
。所以我只使用纯文本,只是为了测试并查看是否一切都按预期工作。工作完成后,您可以再次激活它们。
我还建议您使用另一种哈希解决方案,因为 md5 被认为对密码不安全。请参阅 Best Practices 的 PHP 手册页。