【问题标题】:Nesting foreach loops with PDO statements使用 PDO 语句嵌套 foreach 循环
【发布时间】:2013-11-01 16:09:42
【问题描述】:

我正在尝试使用 PDO 语句嵌套 foreach 循环(这以前在 mysql 中对我有用,顺便说一句)。第一个示例有效,第二个示例无效。但是我不希望每次都运行 SQL 查询(这不是 PDO 的重点吗?)并且更喜欢使用更像示例 2 的东西。但是,它不会将循环“嵌套”在另一个循环中,似乎,而是先运行,然后再运行。

示例 1)

    foreach($db->query('SELECT country FROM db GROUP BY `country`') as $row1) {
echo $row1['country']."<br/>";

    foreach($db->query('SELECT * FROM db') as $row2) {
        if ($row1['country']==$row2['country']){
            echo $row2['name']."<br/>";
            }
        }
    }

示例 2)

$cntry = $db->query('SELECT country FROM db GROUP BY `country` ');
$rslts = $db->query('SELECT * FROM db');

foreach ($cntry as $row1) {

    echo "<div id='".$row1['country']."'>".$row1['country']."<br/>";

    foreach($rslts as $row2) {
        if ($row1['country']==$row2['country']){
            echo $row2['name']."<br/>";
            }

        };
echo "</div>";
    }

【问题讨论】:

  • 我需要“倒带”结果集吗?或者其他的东西?我看过类似的例子,但不是很清楚
  • 我发现了两种对我有用的方法:1)添加 ->fetchAll();在查询 2) 的末尾添加 $rslts->execute();在只返回一次结果的循环结束时,“重新缠绕”结果。任何关于这些工作的原因、最佳实践等的 cmet 都会非常有用。

标签: php pdo foreach


【解决方案1】:

(这不是 PDO 的重点吗?)

没有。 PDO 的目的是将您的查询发送到数据库服务器并返回结果。但是 PDO 不能减少执行的查询数量。

所以,这里有正确的解决方案:

$stmt = $db->query('SELECT country, name FROM db ORDER BY country, name');
$data = $stm->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP);

foreach ($data as $country => $row)
{
    echo $country."<br/>\n";
    foreach ($row as $name)
    {
        echo $name."<br/>\n";
    }
}

事实上,fetchAll() 只是如下代码的语法糖

$data = array();
while ($row = $stmt->fetch())
{
    $data[] = $row;
}

它只是根据查询结果创建一个常规 PHP 数组。当然,您可以根据需要多次循环该数组。意味着您总是fetchAll() 替换为手动循环结果,当然您可以按照自己的意愿对结果进行分组。

虽然在 $stmt 上使用 foreach 又只是一个语法糖,旨在迷惑 PHP 用户。因为$stmt 不是一个数组,而是一个更复杂的结构。

【讨论】:

  • 嗨,我所说的“这不是 PDO 的意义所在”是我不必一直查询每个实例的数据库。我绝不是指你所指的!谢谢,我试试这个
  • 为避免重复执行查询,您必须正确编写代码。 PDO 不会为你做这件事。
  • 无论哪种方式,PDO 都无法减少执行的查询数。
  • 我更新了我的示例 2,以说明为什么我提到使用循环来构建标记。您能否告诉我您的示例如何将第二组结果嵌套在第一组结果中,在本例中为
    ??
  • 我可以看到在哪里打开 div,但看不到在哪里关闭它,以便将“名称”结果嵌套在其中!?
【解决方案2】:

不确定,但我记得应该是这样的

$cntry = $db->query('SELECT country FROM db GROUP BY `country` ')->fetchAll (PDO::FETCH_COLUMN);
$rslts = $db->query('SELECT * FROM db')->fetchAll(PDO::FETCH_COLUMN);

foreach ($cntry as $row1) {

echo $row1['country']."<br/>";

foreach($rslts as $row2) {
    if ($row1['country']==$row2['country']){
        echo $row2['name']."<br/>";
        }
    }
}

【讨论】:

  • 嗨,你的例子有效,但前提是我拿出 PDO::FETCH_COLUMN
  • 纯 pdo 一年前我用得更多,所以我开始忘记语法 :) ORM 的阴暗面是让你忘记低级代码的语法
猜你喜欢
相关资源
最近更新 更多
热门标签