【问题标题】:MySQLi executing multiple unrelated queries and also executing a prepared statementMySQLi 执行多个不相关的查询并执行准备好的语句
【发布时间】:2014-09-29 18:31:07
【问题描述】:

我正在创建一个动态 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 一起观看 Accessing Databases with Object-Oriented 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();
} ?>

【问题讨论】:

  • 你在结束之前有一个错误,你有吗?当你需要的时候?> 另外,尝试将你的 var1 声明移到你的 bind->param 语句之上。
  • 我一定是在编辑这里的代码时不小心删除了 >,但它在我的实际文件代码中,所以这不是问题。我按照您的建议移动了 var1 声明,但问题仍然存在。
  • 我没有看到您的 if (isset($_GET['search'])) { 在任何地方关闭。你真的应该考虑把你的代码分解成函数。很难以现在的方式阅读。此外,看起来您实际上并没有根据搜索输入进行任何过滤。
  • Patrick - 我编辑了代码以在开头显示所有内容,这显示了 if isset 关闭。由于我是这种 PHP 风格的新手,所以我还没有真正学习过函数。在我继续使用函数之前,我想先让这种方法正常工作。
  • 我知道你是 PH​​P 新手,但就像任何其他语言一样,你应该学习构建类和函数,这样你就可以以模块化的方式构建你的网站,特别是如果它们不相关,如果他们是那么你应该以某种方式加入查询

标签: php sql mysqli


【解决方案1】:

看来我发现了问题。基本上,问题在于 MySQLi 认为可能会有更多结果,并且在存储搜索查询的结果或关闭语句之前,它不会运行任何进一步的语句或查询。在我尝试运行子导航查询之前,我最初并没有这样做。我现在移动了这行代码 $stmt->store_result();在 $stmt_bind_result($heading, $details) 下;现在所有查询都可以正常工作了。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-15
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    • 2014-06-16
    • 1970-01-01
    • 2012-02-16
    • 1970-01-01
    相关资源
    最近更新 更多