Php 从函数返回的$stmt与函数内部的不同

Php 从函数返回的$stmt与函数内部的不同,php,mysqli,Php,Mysqli,下面是我创建DB连接的函数: function get_db_connection() { $host = "127.0.0.1:3306"; $username = "root"; $password = ""; $db = "crm"; return mysqli_connect($host, $username, $password, $db); } 以下是我使用查询

下面是我创建DB连接的函数:

function get_db_connection()
{
    $host = "127.0.0.1:3306";
    $username = "root";
    $password = "";
    $db = "crm";

    return mysqli_connect($host, $username, $password, $db);
}
以下是我使用查询的函数:

function query_user_by_username($username)
{
    $conn = get_db_connection();

    $stmt = $conn->prepare("SELECT * FROM `users` WHERE `username`=?");
    $stmt->bind_param("s", $username);
    $stmt->execute();
    //var_dump($stmt->get_result()->fetch_assoc());

    return $stmt;
}
当我在函数中执行
var\u dump
时,我得到
NULL
,这对于当前场景来说是非常好的响应

但是,当我从另一个地方调用此函数时,在执行相同的
var\u dump
时会出现错误

示例代码:

require_once(__DIR__ . '/../../db/dbh.inc.php');

$db_response = query_user_by_username("zxc");
var_dump($db_response->get_result()->fetch_assoc());
执行此操作时,我得到以下错误:

致命错误:未捕获错误:在第17行的/opt/lampp/htdocs/src/signinscreen/repo/signin.inc.php中调用boolean上的成员函数fetch_assoc():17堆栈跟踪:#0{main}抛出/opt/lampp/htdocs/src/signinscreen/repo/signin.inc.php

出于某种原因,函数中的
$stmt->get_result()
是一个实际的
对象
,但从函数返回时,它是
bool


为什么?

当您调用
get\u db\u connection()
时,它会创建mysqli类的新实例,并打开到MySQL服务器的连接。只要有一个PHP变量指向该对象,该对象就会一直存在。在您的情况下,连接仅在
query\u user\u by\u username()函数的作用域内有效

function query_user_by_username(mysqli $conn, $username)
{
    $stmt = $conn->prepare("SELECT * FROM `users` WHERE `username`=?");
    $stmt->bind_param("s", $username);
    $stmt->execute();

    return $stmt;
}
默认情况下,mysqli中准备好的语句会生成无缓冲的结果。结果不会自动从MySQL服务器获取,您需要调用
get\u result()
store\u result()
或逐行获取。要从服务器获取结果集,必须打开连接

当您离开
query\u user\u by\u username()
函数时,PHP将关闭连接并放弃任何剩余结果。当您尝试在函数外部使用
get\u result()
获取结果集时,由于连接已关闭,因此无法获取任何结果

要解决此问题,应将mysqli连接作为参数传递给函数

function query_user_by_username(mysqli $conn, $username)
{
    $stmt = $conn->prepare("SELECT * FROM `users` WHERE `username`=?");
    $stmt->bind_param("s", $username);
    $stmt->execute();

    return $stmt;
}
然后,您应该确保连接在代码需要的时间内一直存在。实际上,这意味着您应该只创建mysqli类的一个实例,并将其作为参数传递给需要它的函数

require_once(__DIR__ . '/../../db/dbh.inc.php');
$conn = get_db_connection();

$db_response = query_user_by_username($conn, "zxc");
var_dump($db_response->get_result()->fetch_assoc());
正如您所看到的,mysqli是一个低级API,使得处理数据库操作变得困难。因此,最好使用PDO。如果您希望继续使用MySQL,则可以考虑编写或编写函数,这样就不会将底层MySQL函数暴露给业务层。例如:

function query_user_by_username(mysqli $conn, $username): ?array
{
    $stmt = $conn->prepare("SELECT * FROM `users` WHERE `username`=?");
    $stmt->bind_param("s", $username);
    $stmt->execute();

    // only return the data, not the mysqli object
    return $stmt->get_result()->fetch_assoc()
}

当您调用
get\u db\u connection()
时,它将创建mysqli类的新实例,并打开到MySQL服务器的连接。只要有一个PHP变量指向该对象,该对象就会一直存在。在您的情况下,连接仅在
query\u user\u by\u username()函数的作用域内有效

function query_user_by_username(mysqli $conn, $username)
{
    $stmt = $conn->prepare("SELECT * FROM `users` WHERE `username`=?");
    $stmt->bind_param("s", $username);
    $stmt->execute();

    return $stmt;
}
默认情况下,mysqli中准备好的语句会生成无缓冲的结果。结果不会自动从MySQL服务器获取,您需要调用
get\u result()
store\u result()
或逐行获取。要从服务器获取结果集,必须打开连接

当您离开
query\u user\u by\u username()
函数时,PHP将关闭连接并放弃任何剩余结果。当您尝试在函数外部使用
get\u result()
获取结果集时,由于连接已关闭,因此无法获取任何结果

要解决此问题,应将mysqli连接作为参数传递给函数

function query_user_by_username(mysqli $conn, $username)
{
    $stmt = $conn->prepare("SELECT * FROM `users` WHERE `username`=?");
    $stmt->bind_param("s", $username);
    $stmt->execute();

    return $stmt;
}
然后,您应该确保连接在代码需要的时间内一直存在。实际上,这意味着您应该只创建mysqli类的一个实例,并将其作为参数传递给需要它的函数

require_once(__DIR__ . '/../../db/dbh.inc.php');
$conn = get_db_connection();

$db_response = query_user_by_username($conn, "zxc");
var_dump($db_response->get_result()->fetch_assoc());
正如您所看到的,mysqli是一个低级API,使得处理数据库操作变得困难。因此,最好使用PDO。如果您希望继续使用MySQL,则可以考虑编写或编写函数,这样就不会将底层MySQL函数暴露给业务层。例如:

function query_user_by_username(mysqli $conn, $username): ?array
{
    $stmt = $conn->prepare("SELECT * FROM `users` WHERE `username`=?");
    $stmt->bind_param("s", $username);
    $stmt->execute();

    // only return the data, not the mysqli object
    return $stmt->get_result()->fetch_assoc()
}

欢迎来到堆栈溢出。请学习如何使用堆栈溢出,并阅读如何提高问题的质量。然后,你的问题包括完整的源代码,你有一个,它可以被编译和测试的其他人。有关SQL相关问题,请参见。您首先需要自助。查看错误消息。它说调用了fetch_assoc()。现在看看代码。fetch_assoc()不在任何地方,无法看到。首先使代码和错误消息匹配。@YourCommonSense我修复了代码是的,请参阅。您的
get\u db\u connection()
每次都返回一个新实例,因此当您离开函数时,GC将收集它并丢弃您的结果。最好的解决方案是使用PDO而不是mysqli。如果您想继续使用mysqli,那么您应该只创建一个mysqli实例,并将其作为参数传递给您的函数。欢迎使用堆栈溢出。请学习如何使用堆栈溢出,并阅读如何提高问题的质量。然后,你的问题包括完整的源代码,你有一个,它可以被编译和测试的其他人。有关SQL相关问题,请参见。您首先需要自助。查看错误消息。它说调用了fetch_assoc()。现在看看代码。fetch_assoc()不在任何地方,无法看到。首先使代码和错误消息匹配。@YourCommonSense我修复了代码是的,请参阅。您的
get\u db\u connection()
每次都返回一个新实例,因此当您离开函数时,GC将收集它并丢弃您的结果。最好的解决方案是使用PDO而不是mysqli。如果您想继续使用mysqli,那么您应该只创建一个mysqli实例,并将其作为参数传递给您的函数。