简体   繁体   English

PHP在准备好的声明中准备了声明

[英]PHP prepared statement within a prepared statement

I'm going through a video tutorial about doing a menu using a db. 我正在阅读有关使用数据库执行菜单的视频教程。 Instead of doing it with procedural PHP like in the video, I tried doing it with prepared statements OOP style. 我没有像在视频中那样使用程序化PHP,而是尝试使用预备语句OOP样式。 It doesn't work and I can't figure out why. 它不起作用,我无法弄清楚为什么。

It runs fine until line 17, where it dies with this error: 它运行良好,直到第17行,它出现此错误:

Fatal error: Call to a member function bind_param() on a non-object in C:\\wamp\\www\\widget_corp\\content.php on line 17

And here's the code: 这是代码:

    <?php
        $query = $connection->prepare('SELECT menu_name, id FROM subjects ORDER BY position ASC;');
        $query->execute();
        $query->bind_result($menu_name, $sid);

        while ($query->fetch()){
            echo "<li>{$menu_name} {$sid}</li>";

            $query2 = $connection->prepare('SELECT menu_name FROM pages WHERE subject_id = ? ORDER BY position ASC;');
            $query2->bind_param("i", $sid); //This is line 17
            $query2->execute();
            $query2->bind_result($menu_name);
            echo "<ul class='pages'>";              
            while ($query2->fetch()){
                echo "<li>{$menu_name}</li>";
            }
            echo "</ul>";

        }
        $query->close();
    ?>

Is it impossible to do a prepared statement within stmt->fetch();? 是不可能在stmt-> fetch()中做一个准备好的声明;?

Figured it out: 弄清楚了:

After executing and binding the result, it has to be stored (if another prepared statement is to be put in the fetch). 在执行并绑定结果之后,必须将其存储(如果要将另一个预准备语句放入获取中)。 So the fetching in this case has to be read from a buffered result. 因此,必须从缓冲结果中读取此情况下的提取。

In other words, can't execute another query until a fetch on the same connection is in progress. 换句话说,在同一连接上的提取正在进行之前,无法执行另一个查询。

The working code: 工作代码:

$query = $connection->prepare("SELECT menu_name, id FROM subjects ORDER BY position ASC;");
$query->execute();
$query->bind_result($menu_name, $sid);
$query->store_result();
$stmt = mysqli_prepare($con,"SELECT menu_name, id FROM subjects ORDER BY position ASC");
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $menu_name, $id);
while (mysqli_stmt_fetch($stmt))
{
 $stmt2 = mysqli_prepare($con2,"SELECT menu_name FROM pages WHERE subject_id = ? ORDER BY position ASC;");
 mysqli_stmt_bind_param($stmt2,$id);
 mysqli_stmt_execute($stmt2);
 mysqli_stmt_bind_result($stmt2, $name);
 while (mysqli_stmt_fetch($stmt2))
  echo $name;
}

look at the $con and $con2, you can not execute a prepare statement within another ps using the same connection !!! 看看$ con和$ con2,你不能使用相同的连接在另一个ps内执行一个prepare语句!

Yes, you can have several prepared statements : one of the ideas of prepared statements is " prepare once, execute several times ". 是的,你可以有几个准备好的陈述:预备陈述的一个想法是“ 准备一次,多次执行 ”。

  • So, you should prepare the statement outside of the loop -- so it's prepared only once 所以,你应该在循环之外准备语句 - 所以它只准备了一次
  • And execute it, several times, insidde the loop. 并且多次执行它,使循环无效。


The Fatal error you get means that $query2 on line 17, is not an object -- which means the prepare failed. 你得到的致命错误意味着第17行的$query2不是一个对象 - 这意味着prepare失败。

A prepare typically fails when there is an error in it ; prepare通常在出现错误时失败; are you sure your query is valid ? 你确定你的查询有效吗? The tables and columns names are OK ? 表和列名称可以吗?

You should be able to get an error message, when the prepare fails, using mysqli->error() -- or PDO::errorInfo() prepare失败时,您应该能够使用mysqli->error() - 或PDO::errorInfo()获取错误消息

You don't say what DB extension you are using but you don't seem to test the return value of any function you are using. 你没有说你正在使用什么数据库扩展,但你似乎没有测试你正在使用的任何函数的返回值。 You can't assume that DB calls will always run flawlessly. 您不能假设数据库调用总是运行良好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM