MySQLi执行多个不相关的查询并执行预准备语句

时间:2014-09-29 18:31:07

标签: php sql mysqli

我正在创建一个动态的PHP网站,其中几乎所有网站上的内容,包括动态生成的导航。我正在创建一个测试页面(test.php),因为我是PHP的新手,在进行多个查询时加上一个准备好的语句,因为我在页面上有一个搜索表单。基本上我想要做的是,在SQL中,为父级= 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&amp; search = Go),那么我会收到错误。该页面将显示第一个LI,但是当它点击第二个查询时它就会完全停止。所以它看起来像:

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

如果我删除了预准备语句的所有内容,那么&#34;子导航&#34; /嵌套查询就可以正常工作。如果我删除了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();
} ?>

1 个答案:

答案 0 :(得分:0)

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

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