2011-04-07 255 views
1

我正在浏览关于使用数据库执行菜单的视频教程。我没有像在视频中那样使用过程式PHP来做这件事,而是试着用准备好的语句OOP风格来做到这一点。它不起作用,我不明白为什么。PHP在准备好的语句中准备了语​​句

它运行良好,直到第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

而这里的代码:

<?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(); 
    ?> 

是不可能内stmt-做一份准备好的声明>取();?

+0

您使用的是mysqli扩展,对不对?你有没有考虑过使用PDO?对于PDO,你可以将异常设置为“错误处理程序”,这会让你更难以错过sql错误(就像这种情况下最可能由第16行导致的错误;-)) – VolkerK 2011-04-07 10:27:36

+0

是的,它是mysqli,但它不是sql错误。在终端中运行SQL查询,工作正常。 – thekodols 2011-04-07 10:59:21

回答

8

想通了:

执行和结果结合后,它必须被存储(如果另一个准备语句是在获取被投入)。所以在这种情况下的读取必须从缓冲结果中读取。

换句话说,直到在同一连接上进行提取操作正在进行时,才能执行另一个查询。

工作代码:

$query = $connection->prepare("SELECT menu_name, id FROM subjects ORDER BY position ASC;"); 
$query->execute(); 
$query->bind_result($menu_name, $sid); 
$query->store_result(); 
+0

“...它必须被储存“..救生员! – JohnA10 2015-08-26 22:31:26

0

是的,你可以有几个准备好的陈述:准备陈述的想法之一是“准备一次,执行几次”。

  • 所以,你应该准备语句的循环之外 - 所以它的准备只有一次
  • 并执行它,好几次insidde循环。


你的致命错误意味着$query2第17行,是不是一个对象 - 这意味着失败prepare

A prepare通常在发生错误时失败;你确定你的查询是有效的吗?表格和列名称都可以吗?

你应该能够得到一个错误信息,当prepare失败,请使用mysqli->error() - 或PDO::errorInfo()

+0

如果我将它从循环中取出,查询就可以正常工作。而“i”是整数,因此它知道把一个整数代替?。它不受名称的约束。 – thekodols 2011-04-07 10:34:43

+0

Humph,对不起,我忘了这是如何工作:-(我已经删除了我的答案的这部分...你是否尝试得到由准备造成的错误信息? – 2011-04-07 10:37:23

+0

如果我把内部准备,并把它放在外面我只是没有做任何事情,没有任何错误,但没有结果,也没有得到任何其他的错误信息,除了原来的准备。(顺便说一句,你有一些非常快速的反应时间,非常感谢你) – thekodols 2011-04-07 10:57:40

0

你不说你用的是什么DB扩展,但你似乎并不测试返回您正在使用的任何功能的值。您不能认为数据库调用总是完美无缺。

2
$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; 
} 

看看$ CON和$ CON2,你不能执行使用相同的连接再使用ps内准备的语句!

+0

在这种情况下,不需要存储结果,所以你节省了内存和时间:) – Sourav 2011-04-07 12:51:44