【问题标题】:First attempt at a MySQLi Prepared Statement第一次尝试 MySQLi Prepared Statement
【发布时间】:2014-02-15 05:17:42
【问题描述】:

我正在尝试将一些 mysqli 查询重写为准备好的语句(我的第一次尝试)。前两行注释的行是运行良好的旧查询。剩下的就是我尝试编写一个准备好的语句:

//$sql = "SELECT hashed_password FROM Administrators WHERE user_name='$username'";
//$result = mysqli_query($link, $sql);

//switch to prepared statement
$stmt = mysqli_stmt_init($link);
$result = false;
if (mysqli_stmt_prepare($stmt, 
    'SELECT hashed_password FROM Administrators WHERE user_name=?')) 
{

    /* bind parameters for markers */
    mysqli_stmt_bind_param($stmt, "s", $username);

    /* execute query */
    $result = mysqli_stmt_execute($stmt);

    /* close statement */
    //mysqli_stmt_close($stmt);
}

if (!$result) {
    mysqli_close($link);
    die("Error running query " . mysqli_error($link));
}

if (mysqli_num_rows($result) == 0) {
        mysqli_close($link);
        echo "No such user";
        die();
    }

发生的错误在最后一行显示,但显然可以追溯到前面的一行。

谁能告诉我我做错了什么?我直接从 PHP 文档中获取了这个,但显然我遗漏了一些东西。谢谢!

编辑:感谢那些指出我忘记分配查询返回值的人。我已经合并了这些 cmets 并修改了我的代码。但是,我仍然无法成功运行查询。现在我得到这个错误:

Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given in /home/content/07/11347607/html/RevRunning/scripts/administration/login.php on line 53 No such user

相信我,我在 UI 中输入的用户确实存在,所以我的代码仍然有问题。再次感谢您的帮助。

【问题讨论】:

  • 你有if (!$result),因为你从来没有设置$result,它总是会调用die(...

标签: php mysqli prepared-statement


【解决方案1】:

为了测试查询是否失败,您需要从mysqli_stmt_execute 获取返回布尔值,如下所示:

$result = mysqli_stmt_execute($stmt);

然后你就可以检查了:

if (!$result) {
 // if you get here it mean $result is false
 //therefore it failed
}

【讨论】:

  • 谢谢。不敢相信我没有注意到这一点。我仍然遇到问题并更新了我的帖子。
  • @usr55410 该错误通常意味着上次执行的查询失败。回显您的查询并直接针对数据库进行尝试。查询中使用的字段名和表名是否正确?
  • 谢谢。我意识到查询失败了。这就是为什么我发布了两条注释行,您可以在其中看到有效的旧查询。如果旧查询有效,并且参数完全相同,那么问题必须在新代码中的某个地方(我假设)。你同意吗?
  • 是的,我同意这意味着问题是代码尝试合并两个条件if (!$result || mysqli_num_rows($result) == 0)
  • @usr55410 你也可以得到这样的计数$row_cnt = $result->num_rows;
【解决方案2】:

您收到此Couldn't fetch mysqli 错误是因为您正在访问已关闭的对象。

如您所见...

   /* close statement */
    mysqli_stmt_close($stmt);  //<-------- As you have closed it !!!!
}

if (!$result) {    //<------ But you are accessing it here !
    mysqli_close($link);
    die("Error running query " . mysqli_error($link));
}

【讨论】:

  • 谢谢。我尝试删除 mysqli_stmt_close 行(请参阅我的帖子的编辑),但我仍然得到类似的结果。
  • 但是$result 变量没有在任何地方声明,所以它肯定会像你所做的!$result 一样进入if 语句中
  • 谢谢,但请仔细查看。 $result = false; 是第二行代码。
  • if (!$result) { 应该是 if (!$stmt) {
  • 再次感谢您。我感谢您的所有帮助。我试过了,但得到了完全相同的错误信息。请注意,执行在最后一个 if 块内终止,这表明 $result 有一个在查询中分配的值,但返回的数据集是空的(即有 0 条记录)。
【解决方案3】:

经过多次反复试验,我似乎遇到了一些问题。

首先,这是错误的:

/* execute query */
$result = mysqli_stmt_execute($stmt);

有一个将结果绑定到变量的命令。正确的做法是这样的:

/* execute query */
mysqli_stmt_execute($stmt);

/* Bind results to variable */
mysqli_stmt_bind_result($stmt, $result);

我的另一个问题是解释返回值(即存储在$result 中的内容)。当我使用未准备好的语句时,返回值是我需要先使用mysqli_fetch_array($result) 解包的数据集。我可以用mysqli_num_rows 测试这个数据集中的行数。至少在这种情况下,返回值只是一个字符串,但我仍然必须用mysqli_fetch_array 解开它。

但是,没有准备好的语句。现在的返回值只是一个字符串,所以我需要做的就是测试我是否得到了一些东西是这样的:

if (!stmt) { // do before closing $stmt
    mysqli_close($link);
    echo "Query Error";
    die();
}

if (!$result) {
    mysqli_close($link);
    echo "No results returned";
    die();
}

这只是基于我自己的测试并找到了一个成功的解决方案。如果我说的有什么不正确的地方,或者如果有人可以给出更好的答案,请随时发表评论。

感谢大家的帮助。

【讨论】:

  • 如果浏览了一些相关的问题,你会为自己省去很多麻烦。你不只是第一次尝试准备好的语句,你知道的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-26
  • 2019-10-27
相关资源
最近更新 更多