【问题标题】:Problem with putting Category "parent" and Subcategory ''child'' into a table将类别“父”和子类别“子”放入表中的问题
【发布时间】:2021-05-03 19:50:34
【问题描述】:

我试图打印一个父子树的数组。我使用的代码似乎没有打印任何内容。

<?php
$sql = "

SELECT *,
       category_name parent_category_name,
       '' path
FROM categories
LEFT JOIN categories ON parent_id = id
ORDER BY parent_id, id

";

function print_row ( $rowdata )
{
?>
                  <tr>
                      <td>
                          <?=$rowdata['id']?>
                      </td>
                      <td>
                          <?=$rowdata['path']?>
                      </td>
                      <td>
                          <?=$rowdata['type']?>
                      </td>
                      <td>
                          <?=$rowdata['status']?>
                      </td>
                  </tr>
<?php

}

$stmt  = $dbh->prepare($sql);
$stmt->execute();
$result = $stmt->get_result();
$data = $result->fetch_all(MYSQLI_ASSOC);

$printed = array();

foreach ($data as $row)
{

   if ( $row['parent_id'] == '' )
   {
      $row['path'] = $row['category_name'] . '/';
      $printed[$row['id']] = $row;
   }
   else
   {
      $row['path'] = $printed[$row['parent_id']]['path'] . $row['category_name'] . '/';
      $printed[$row['id']] = $row;
   }
}


array_multisort(array_column($printed, 'path'), SORT_ASC, $printed);

foreach ( $printed as $prow )
{
   print_row ( $prow );
}
?>
</table>

Mysql 分类

id parent_id category_name category_description
1 0 General desc
2 1 Announcements desc

我要创建的结果是这样的

有谁知道如何解决这个问题,因为&lt;?php ?&gt; 也会导致 HTML 的其他部分消失。

【问题讨论】:

    标签: php mysql parent-child categories


    【解决方案1】:

    首先,您可以使用零 parent_id 获取父母数据:

    $parentsData = $dbh->prepare("SELECT * from categories where parent_id=0")->execute()->get_result()->fetch_all(MYSQLI_ASSOC);
    

    在 foreach parentsData 中,使用父 ID 再次发送查询:

    foreach($parentsData as $parentRow){
      echo 'parent title: '.$parentRow['category_name'].'<br>child list: ';
      $childs = $dbh->prepare("SELECT * from categories where parent_id=".$parentRow['id'])->execute()->get_result()->fetch_all(MYSQLI_ASSOC);
      foreach($childs as $child){
        echo 'parent title: '.$child['category_name'];
      }
    }
    

    【讨论】:

      【解决方案2】:

      甚至在测试之前,你放在那里的查询对我来说看起来很奇怪。但无论如何我都会尝试测试它。在测试之后,您的查询会因错误而崩溃。

      CREATE TABLE categories (
        id INT AUTO_INCREMENT,
        parent_id INT,
        category_name VARCHAR(256),
        category_description VARCHAR(256),
        PRIMARY KEY(id)
      );
      
      INSERT INTO categories(category_name, category_description) VALUES 
           ('General', 'desc'),
           ('Announcements', 'desc');
           
      UPDATE categories SET parent_id = 0 WHERE id = 1;
      UPDATE categories SET parent_id = 1 WHERE id = 2;
      

      我使用这个脚本来构建表,当你在你的问题中进行查询时,它会崩溃并出现以下错误:Not unique table/alias: 'categories'。这是小提琴链接:http://sqlfiddle.com/#!9/4b5d95/22

      现在这个错误只是意味着,您有 2 个表使用相同的名称/别名,即类别和本身。那么我认为你真正想要的查询是这样的

      SELECT 
        child.id AS id,
        child.category_name AS category_name,
        child.category_description AS category_description,
        child.parent_id AS parent_id,
        parent.category_name AS parent_category_name
      FROM 
        categories AS child
        LEFT JOIN categories AS parent 
          ON parent.id = child.parent_id
      ORDER BY parent.parent_id, child.id
      

      注意我是如何将“孩子”和“父母”的别名放到表格中的?这是必要的,以便 MySql 可以知道您指的是哪个表,这样它就不会被视为“重复”。

      现在,我没有理由这样做SELECT '' AS path,您可以直接在 PHP 中初始化它们。使用* 然后添加category_name parent_category_name 也没有什么意义,* 已经选择了连接表中的所有内容,结果还将包含一些未使用或冗余的列,所以我认为你最好只是选择你需要的。

      我的查询结果:

      id category_name category_description parent_id parent_category_name
      1 General desc 0 (null)
      2 Announcements desc 1 General

      毕竟,我假设您使用的实际查询可能会有所不同?而你发布的只是一个糟糕的复制粘贴什么的,但如果它是你正在使用的,那就是问题所在。

      编辑:实际上在您的 cmets 之后,您可以使用常规选择来执行此操作

      SELECT * FROM categories
      

      它也可以正常工作

      编辑:我已经测试了你的 PHP 部分代码,除了这 2 个之外,它大部分都可以正常工作

      // Maybe instead of these 2
      <?=$rowdata['type']?>
      <?=$rowdata['status']?>
      // You want this:
      <?=$rowdata['category_name']?>
      <?=$rowdata['category_description']?>
      

      数据不包含“类型”和“状态”列,所以我不确定你想要什么。除此之外,您需要将 print_row 循环包装到适当的表中,如下所示:

      ...
      ?>
      <table>
          <tr>
              <th>Id</th>
              <th>Path</th>
              <th>Name</th>
              <th>Desc</th>
          </tr>
      <?php
          foreach ( $printed as $prow )
          {
              print_row ( $prow );
          }
      ?>
      </table>
      ...
      

      然后在修改那个 2 并将其插入 HTML 之后,我得到了这样的东西:

      <head>
        <style>
          table, th, td {
            border: 1px solid black;
          }
        </style>
      </head>
      <body>
        <table>
          <tbody>
            <tr>
              <th>Id</th>
              <th>Path</th>
              <th>Name</th>
              <th>Desc</th>
            </tr>
            <tr>
              <td>1</td>
              <td>General/</td>
              <td>General</td>
              <td>desc</td>
            </tr>
            <tr>
              <td>2</td>
              <td>General/Announcements/</td>
              <td>Announcements</td>
              <td>desc</td>
            </tr>
          </tbody>
        </table>
      </body>

      【讨论】:

      • 不需要 parent_category_name,因为 parent_id 应该能够检索父类别。
      • 是的,您也可以这样做,但这意味着您甚至不需要连接,只需使用原始行结果而无需任何连接即可。无论如何,那么您的问题的状态如何?修复查询后还有问题吗?
      • 我仍然找不到循环打印类别和子类别的方法
      • @Babo 查看我的编辑,了解您可能需要修复的问题。老实说,在来回之后,我认为您的问题还不够清楚。起初,我以为是因为你不明白问题所在。但显然你确实有一些了解。现在我看到你的代码最后有一个&lt;/table&gt;。但我没有看到顶部,所以也许这就是问题所在?无论如何,如果这不是你的问题,你可能需要给我一个更好的情况解释,因为你的代码至少在某种程度上,没有有任何问题(我也测试过这个)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      • 1970-01-01
      • 2011-07-30
      相关资源
      最近更新 更多