php - 尝试学习 mysqli,我的语句实际上都没有返回结果

标签 php mysql mysqli

正如它听起来的那样,我的检索语句都没有按应有的方式检索数据。这很奇怪,就好像我复制了确切的查询并将其放入 phpMyAdmin 并在那里运行它一样,它会返回应有的结果。

插入语句和类似的工作,例如:

    // On first connect to database, create a user to hold data for users not logged in
    $result = $db->query("SELECT id FROM users WHERE id = 1");
    if ($result->num_rows == 0) {
        $db->query("INSERT INTO users (id, username, email, password) VALUES (1, 'anonymous', 'anonymous', '" . password_hash("...", PASSWORD_BCRYPT) . "')");
    }

然后用户按预期输入。

但是如果我运行这样的语句:

    $result = $db->query("SELECT id, username, password FROM users WHERE email = $email");
    $row = $result->fetch();

我收到以下错误:“ fatal error :调用非对象上的成员函数 fetch()”

在 phpMyAdmin 中运行完全相同的语句会按预期返回行。

它只适用于一个区域,但是:

            if ($result = $db->query("SELECT username, wins, losses FROM users ORDER BY wins DESC LIMIT 10")) {
                while ($row = $result->fetch_assoc()) {
                    echo "<tr><td>" . $row["username"] . "</td> <td>" . $row["wins"] . "</td> <td>" . $row["losses"] . "</td></tr>\n";
                }
            }

返回预期结果。不过,我不知道为什么。

我不确定我的文件结构是否重要,我有一个我需要的 config.php 文件,它有连接信息。其余部分在我的 index.php 文件中。

这是 config.php:

<?php
    $db_host = $_SERVER["SERVER_NAME"];
    $db_user = "...";
    $db_pass = "...";
    $db_database = "hangman";

    $db = new mysqli($db_host, $db_user, $db_pass, $db_database);

    if ($db->connect_error) {
        echo "Could not connect to database.";
        exit;
    }
    // On first connect to database, create a user to hold data for users not logged in
    $result = $db->query("SELECT id FROM users WHERE id = 1");
    if ($result->num_rows == 0) {
        $db->query("INSERT INTO users (id, username, email, password) VALUES (1, 'anonymous', 'anonymous', '" . password_hash("...", PASSWORD_BCRYPT) . "')");
    }
?>

我可以包含更多我的 PHP,请说什么,这让我发疯。

最佳答案

首先,虽然您的输入来自数据库,但您仍然不应该相信任何不是您自己输入的数据。

$result = $db->query("SELECT id, username, password FROM users WHERE email = $email");
$row = $result->fetch();

这有一个语法错误:$email需要引号,因为它是一个字符串。

你真的确定你正在连接到 $_SERVER["SERVER_NAME"] ?
你真的应该只连接到 localhost相反……

测试查询的一个技巧是将其包装在 if 中 block ,因为如果失败,FALSE返回而不是对象。你不能调用 false->fetch() .

if ($result = $db->query($sql)) {
    //do stuff, fetch data, etc.
} else {
    if (DEBUG) { // define('DEBUG', 1);
        trigger_error("Query Failed; Fix it: " . htmlspecialchars($sql));
    } else {
        header("Location: /oops.php");
    }
}

此外,使用 prepare 为了这。事实上,对插入数据或包含用户输入的所有内容都使用 prepare。并在任何循环之前定义它。

if ($x = $db->prepare("SELECT id, username, password FROM users WHERE email = ?")) {
    $x->bind_param("s", $email);
    $x->execute();
    $x->bind_result($id, $user, $pass);
    $x->fetch();
}

Fetch 并不完全符合您的习惯。它在执行查询后获取数据。 fetch_assoc将从结果对象中获取关联数组。

此外,在您的数据库中查询 users.id = 1每次有人加载页面都不是一个好主意。将其粘贴在安装脚本中。并让匿名用户有一个不可能的密码(又名而不是 $2y$13$<hash> 它将是 Nope, not happenin' 或其他东西)。

此外,您直接从数据库回显到 HTML 中。如果你不清理,我可以创建一个像 <script src=""></script> 这样的用户名并从最新的漏洞中获得很多乐趣。 sanitizer ~

更新:阅读您的代码后,我发现了您的问题。

$stmt1 = $db->prepare("SELECT wins FROM users WHERE id = ?");
$stmt2 = $db->prepare("SELECT losses FROM users WHERE id = ?");
$stmt1->bind_param($_SESSION["id"]);
$stmt2->bind_param($_SESSION["id"]);
$stmt1->execute();
$stmt2->execute();
$row1 = $stmt1->fetch();
$row2 = $stmt2->fetch();

这里有三个问题1

第一个问题是您一次只能在给定连接上进行一次准备调用。我相当确定这是因为它是一个阻塞的 API 调用。如果我错了,请纠正我。

第二个是您没有为 bind_param 指定类型打电话。您必须为您在此处指定的任何内容分配一个类型。 s = 字符串,i = 整数。

第三个是您根本不在此处绑定(bind)任何结果变量。使用准备好的查询时,您必须绑定(bind)变量。这是针对此实例的修复:

if ($query = $db->prepare("SELECT wins, losses FROM users WHERE id = ?")) {
    $query->bind_param("s", $_SESSION["id"]);
    $query->execute();
    $query->bind_result($wins, $losses);
    if (!$query->fetch()) { // fetch one row from database.
        logout(); // or equiv.
    }
} else {
    if (DEBUG) {
        echo "Malformed SQL or In-use thread. SQL: <sql here>";
    } else {
        header("Location: /oops.php");
    }
}

1。或者 4,如果您计算使用多个查询来执行此操作。

关于php - 尝试学习 mysqli,我的语句实际上都没有返回结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15012227/

相关文章:

mysql - 如何将数据库中的表转换为文本文件?

php - MySQL PHP 查询问题

php - Mysql插入数据如果不存在否则显示警告

php - 有没有更优雅的方法在 PHP 中格式化 MySQL 结果?

php - PHP 连接出现问题

php - 如何使用 PHP 和 MySQL 处理带链接的数据库信息更改?

php - 根据数据库 pdo 检查用户名

php - 通过 Javascript 传递 MySQL 查询

php - 如何在登录表单php上使用密码验证

php - 用php创建数据库