首页 > 解决方案 > 使用选择准备好的语句获取用户名

问题描述

我写了这段代码,但它只是输出“1”。它应该输出所选用户的用户名。

$uid = $_GET['id'];
if (empty($uid)) {
    echo "Error: Wrong input of values.";
} else {
    $stmt = $conn->prepare("SELECT username FROM usersinfo WHERE id = ?");
    $stmt->bind_param("s", $uid);
    $stmt->execute();
    $result = $stmt->fetch();
    echo $result;
    $stmt->close();
    $conn->close();
}

标签: phpmysqliprepared-statement

解决方案


fetch()不返回结果。该函数没有返回有用的信息。你需要做的是得到 mysqli 结果。有两种方法可以做到这一点。

更简单的方法:

$stmt = $conn->prepare("SELECT username FROM usersinfo WHERE id = ?");
$stmt->bind_param("s", $uid);
$stmt->execute();
$result = $stmt->get_result(); // Get the result of the above statement.
$firstRow = $result->fetch_array(); // Get the first result into an array
if ($firstRow) {
    echo $firstRow[0];
    //or
    echo $firstRow['username'];
}

在这里,我们得到 mysqli 结果对象,然后我们要求单行。

另一种使用方式bind_result()

$stmt = $conn->prepare("SELECT username FROM usersinfo WHERE id = ?");
$stmt->bind_param("s", $uid);
$stmt->execute();
$stmt->bind_result($username); // Bind a single column from SELECT to a single variable
$stmt->fetch(); // Fetch the first row. It will populate the variable
echo $username;

在我看来,这更难阅读。此外,如果您想获得更多列,它很快就会变得非常复杂。

说实话mysqli不是很友好,用起来很麻烦。我强烈建议切换到 PDO,但是如果您不能尝试将 mysqli 函数封装在某个类或函数中。YCS 有一个这样的辅助函数的例子。我最近写了一个示例,说明如何使用包装类扩展 mysqli 类。

我在 mysqli 类中添加了一个简单的方法,看看这些语句变得多么简单。

class DBClass extends mysqli {
    public function __construct(
        $host = null,
        $username = null,
        $passwd = null,
        $dbname = null,
        $port = null,
        $socket = null
    ) {
        mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
        parent::__construct($host, $username, $passwd, $dbname, $port, $socket);
        $this->set_charset('utf8mb4');
    }

    public function safeQuery(string $sql, array $params = []): ?array {
        $stmt = $this->prepare($sql);
        if ($params) {
            $stmt->bind_param(str_repeat("s", count($params)), ...$params);
        }
        $stmt->execute();
        if ($result = $stmt->get_result()) {
            return $result->fetch_all(MYSQLI_BOTH);
        }
        return null;
    }
}

示例用法:

$results = $conn->safeQuery("SELECT username FROM users WHERE id = ?", [$uid]);
if($results){
    echo $results[0][0]; // first row, first column 
    // or 
    echo $results[0]['username']; // first row, get column by name
}

推荐阅读