需要将MySQL记录转换为JSON树

时间:2011-09-02 20:29:53

标签: php mysql json

我有一些看起来像

的数据集
  

UID |价值| MySQL中的PARENTUID。

如果有人能告诉我如何将其转换为与上面完全相同的JSON树,我真的很感激。

所有值都是字符串。我尝试了StackOverflow的3个解决方案但无法让它们工作。

示例解决方案

Convert PHP array to JSON tree

2 个答案:

答案 0 :(得分:2)

事实证明,关系数据库处理树木非常糟糕。您可能最好尝试使用不同的方法存储数据。如果您对该架构设置了自己的心,那么您基本上有三个选项,其中没有一个非常好。

选项1:

如果您知道树的根并知道树的深度:

SELECT uid, value, parent_uid
FROM your_table level1
LEFT JOIN your_table level2 ON uid = parent_uid
  ON level1.uid = level2.uid
LEFT JOIN your_table level2 ON uid = parent_uid
  ON level3.uid = level3.uid
/* repeat the join until you have gone enough levels down */
WHERE uid = 7 /* or whatever the uid is */
ORDER BY parent_uid, uid

您可以使用它来获取应该在该树的树中的所有内容并在php中重建它。 这个选项很糟糕,因为它很慢而且不灵活。

选项2

如果你知道树的根而不是深度:

<?php
$root_id = 7;
$id_list = array($root_id);
$tree = array();
while (!empty($id_list)) {
    $new_list = array();
    foreach ($id_list as $id) {
       $query = "SELECT * FROM your_table WHERE parent_uid = '$id'";
       $results = mysql_query($query);
       while ($next = mysql_fetch_array($results)) {
          array_push($new_list, $next['uid']);
       }
       // find the item in $tree and add it, also ugly
    }
    $id_list = $new_list;
}
echo json_encode($tree);

尽管更灵活,但此选项更慢且更丑。

选项3:

<?php
$query = "SELECT * FROM your_table ORDER BY parent_uid";
$result = mysql_query($query);
$tree = array();
while ($next = mysql_fetch_array($result)) {
   // attach the item to $tree, this is slow and/or ugly code
}
echo json_encode($tree);
?>

这段代码要求你从mysql中获取整个表,加上它有点慢。

<强>结论:

我没有测试任何这些代码示例,因为它们都很糟糕。 找到树的另一种存储方法。 SQL只是糟透了这份工作。 您可以考虑将其保存在xml或json中以开始,除非数据集太大,在这种情况下您将需要为此任务设计的存储引擎。

答案 1 :(得分:2)

当我发布我的第一个回答时,我想我会说服你找到一个不同的方法。由于没有这样做并且沉迷于很酷的递归算法,这是一个基于我之前的答案中的选项2的工作解决方案。

它将为树中的每个节点调用mysql_query,这对于性能来说非常糟糕,所以不要指望它可以很好地扩展,但对于轻量级使用它不会太慢。

你必须使用to_array()函数才能使json完全按照你想要的方式运行,但这应该会让你离开现场。

<?php

Class Node {
   public $id;
   public $parent_id;
   public $value;
   public $children;
   public $depth;

   function __construct($id, $parent_id, $value) {
      $this->id = $id;
      $this->parent_id = $parent_id;
      $this->value = $value;
      $this->children = array();
      $this->depth = 0;
   }   

   function get_children_from_mysql() {
      $query = "SELECT * FROM your_table WHERE parent_uid = '$this->id'";
      $results = mysql_query($query);
      while ($next = mysql_fetch_array($results)) {
         $next_node = new Node($next['uid'], $next['parent_uid'], $next['value']);
         $this->children[$next_node->id] = $next_node;
         $next_node->get_children_from_mysql();
      }   
   }   

   function to_array() {
      if (count($this->children) > 0) {
         $arr = array();
         foreach ($this->children as $child) {
            array_push($arr, $child->to_array());
         }   
         return array($this->value => $arr);
      } else {
         return $this->value;
      }   
   }   

   function to_json() {
      return json_encode($this->to_array());
   }

}

// you need to know the root uid/value or get it from mysql
$root_uid = 1;
$root_value = "root node value";
$root = new Node($root_uid, 0, $root_value);
$root->get_children_from_mysql(); // magical recursive call

echo $root->to_json();

?>