MySQLi执行多个不相关的查询,还执行一个准备好的语句


MySQLi executing multiple unrelated queries and also executing a prepared statement

我正在创建一个动态PHP网站,其中几乎所有网站上的内容,包括导航,都是动态生成的。我正在创建一个测试页面(test.php),因为我是php的新手,在执行多个查询和一个准备好的语句时遇到了一些问题,因为我在页面上有一个搜索表单。我主要想做的是在SQL中,为parent=0的顶级导航项创建一个查询,并根据搜索结果在另一个表中搜索项。这两个查询是不相关的。在我的身体中,在显示导航的地方,我想嵌套另一个查询,然后使用等于顶级菜单项的当前ID的父项搜索导航项。这是我文档顶部的SQL:

try {
    //db connection is here
    $sql1 = 'SELECT * FROM menu_items WHERE item_parent = 0';
    $result1 = $db->query($sql1);
    if (isset($_GET['search'])) {
        $sqlSearch = "SELECT id, css_body, page_title, meta_description, meta_keywords, heading, details, layout
            FROM content
            WHERE ( details LIKE ? OR heading LIKE ? )";
        $stmt = $db->stmt_init();
        if (!$stmt->prepare($sqlSearch)) {
            $error = $stmt->error;
        } else {
        $var1 = '%' . $_GET['searchterm'] . '%';
        $stmt->bind_param('ss', $var1, $var1);
        $stmt->execute();
        $stmt->bind_result($id, $css_body, $page_title, $meta_description, $meta_keywords, $heading, $details, $layout);
    }
    }
} catch (Exception $e) {
    $error = $e->getMessage();
}

在我的身体里:

    <ul>
    <?php while ($row = $result1->fetch_assoc()) { ?>
    <li><?php echo $row["item_title"]; ?>
    <?php $sql2 = 'SELECT * FROM menu_items WHERE item_parent = ' . $row["item_id"];
        $result2 = $db->query($sql2);
        if (isset($result2)) { ?>
        <ul>
         <?php while ($row2 = $result2->fetch_assoc()) { ?>
        <li><?php echo $row2["item_title"]; ?></li>
        <?php } ?>
   </ul>    
        <?php } ?>
   </li>
   <?php } ?>
  </ul>

有了这些代码,如果我直接进入test.php页面,而不进行搜索,那么一切都会很好。例如,页面看起来像:

<ul>
<li>Page 1</li>
<ul>
<li>Sub Page 1</li>
<li>Sub Page 2</li>
</ul>
<li>Page 2</li>
</ul>

然而,如果我在页面上提交搜索表单(它提交到同一页面,url看起来像test.php?searchterm=my@search&search=Go),那么我会得到一个错误。页面将显示第一个LI,但当它碰到第二个查询时,它就完全停止了。所以它看起来像:

<ul>
<li>Page 1</li>

如果我删除了准备好的语句的所有内容,那么"子导航"/嵌套查询就可以正常工作。如果我删除了menu_items的SQL.php,那么准备好的语句就可以正常工作。问题是当我把所有东西放在一页纸上的时候。如果有人能解释我可能做错了什么,我将不胜感激。我是准备好的语句和面向对象PHP的新手。我在Lynda.com上观看了David Powers的《用面向对象的PHP访问数据库》之后,学会了以上所有内容

这是整个页面的代码:

<?php
try {
    require_once '_includes/mysqli-connect.php';
    $sql1 = 'SELECT * FROM menu_items WHERE item_parent = 0';
    $result1 = $db->query($sql1);
    if (isset($_GET['search'])) {
        $sqlSearch = "SELECT heading, details FROM content WHERE ( details LIKE ? OR heading LIKE ? )";
        $stmt = $db->stmt_init();
        if (!$stmt->prepare($sqlSearch)) {
            $error = $stmt->error;
        } else {
            $var1 = '%' . $_GET['searchterm'] . '%';
            $stmt->bind_param('ss', $var1, $var1);
            $stmt->execute();
            $stmt->bind_result($heading, $details);
        }
    }
} catch (Exception $e) {
    $error = $e->getMessage();
}
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Test</title>
</head>
<body>
<?php if (isset($error)) {
    echo "<p>$error</p>";
}
?>
<ul>
  <?php while ($row = $result1->fetch_assoc()) { ?>
  <li><?php echo $row["item_title"]; ?>
    <?php 
    $sql2 = 'SELECT * FROM menu_items WHERE item_parent = ' .$row["item_id"];
    $result2 = $db->query($sql2);
    if (isset($error)) {
        echo "<p>$error</p>";   
    }
    if (isset($result2)) { ?>
    <ul>
      <?php while ($row2 = $result2->fetch_assoc()) { ?>
      <li><?php echo $row2["item_title"]; ?></li>
      <?php } ?>
    </ul>
    <?php }
    ?>
  </li>
  <?php } ?>
</ul>
<!-- Search form and results below -->
<form method="get" action="<?php echo $_SERVER['PHP_SELF']; ?>">
  <p>
    <label for="searchterm">Enter a name or part of one:</label>
    <input type="search" name="searchterm" id="searchterm"> <input type="submit" name="search" value="Go"></p>
</form>
<?php
if (isset($error)) {
    echo "<p>$error</p>";   
}
$stmt->store_result();
$numrows = $stmt->num_rows;
if ($numrows) {
    echo "<p>Total results found: ". $numrows;  
} else {
    echo "No Results";  
}
while ($stmt->fetch()) {
    echo "<p>Heading: " . $heading . "</p>";    
    echo $details;
    echo "<hr/>";
}
?>
</body>
</html>
<?php 
$result1->free();
$stmt->free_result();
if (isset($db)) {
    $db->close();
} ?>

看起来我发现了问题。基本上,问题是MySQLi认为可能会有更多的结果,在存储搜索查询的结果或关闭语句之前,它不会运行任何进一步的语句或查询。直到我尝试运行子导航查询之后,我才开始做这两件事。我现在移动了这行代码$stmt->store_result();在$stmt_bind_result下($heading,$details);现在所有的查询都工作了。

$stmt->execute();
$stmt->bind_result($heading, $details);
$stmt->store_result();