【问题标题】:Recursive PHP function for adjacency-list display用于邻接列表显示的递归 PHP 函数
【发布时间】:2010-11-22 04:27:06
【问题描述】:

我有一个这样的数据库:

id  text           parent
1   Parent 1        0   
2   Child of 1      1   
3   Sibling         1   
4   Another Parent  0 
5   A first child   4

所以我正在尝试捕获列出父母的树结构。我知道另一个选项(我认为是嵌套集?)但我现在要坚持这个。我现在正试图将数据从数据库中取出并放入 PHP 中的嵌套数组结构中。我有这样的功能:

class Data_Manager
{   
    public $connection = '';
    public $collection = array();

    function __construct() {
        $this->connection = mysql_connect('localhost', 'root', 'root');
        $thisTable = mysql_select_db('data');
            // error handling truncated
    }


    function get_all() {
        $arr = &$this->collection;

        $this->recurseTree('', 0, $arr);
        var_dump($arr);
    }

    function recurseTree($parent, $level, $arrayNode) {
        $result = mysql_query('SELECT * FROM tasks WHERE parent="' . $parent . '";');

        while ($row = mysql_fetch_array($result)) {
            $row['children'] = array(); //where I'd like to put the kids    
            $arrayNode[$row['id']]= $row;
            $this->recurseTree($row['id'], $level+1, $arrayNode[$row['id']]);
        }
    }
}

所以我想提出的是某种嵌套的关联数组树,但我不知道该怎么做。似乎什么都没有写入我传入的数组,而且我在递归中有点迷失自己。任何人都可以帮助我克服这最后的困难,这将导致类似的结果:

[
Parent1 => [
               children => ['Child of 1', 'Sibling']
           ],
AnotherParent => [
                     children => ['First Child']
                 ]
]

而且我不太关心输出的具体形式。它将被转换为 JSON,我还没有编写客户端处理程序,所以不用担心确切的结构。

谢谢!

【问题讨论】:

  • 你试过通过引用传递吗?
  • 当我传入原始实例变量 $collection;我不太了解它是如何工作的,但我是否应该通过递归来始终编辑“母亲”数组?
  • 请参阅stackoverflow.com/questions/3627878/… 以获得大量参考
  • 在进入您的算法之前,您永远不会在这里更改/构​​建任何数据。你需要要么有一个名为 &$arr 的 recurseTree 参数($arr 通过引用,所以当你改变它时它会改变)或者从 recurseTree 返回值并在 get_all 中执行 $arr = recurseTree(...)。我推荐第二种方式。我还强烈建议您停止在 recurseTree 中查询数据库——您已经传入了所有数据。如果必须,请对 parent 的值使用 array_filter - 不要不必要地查询数据库,只是为了按 parent 的值进行过滤。

标签: php recursion hierarchical-data adjacency-list


【解决方案1】:

试试这个。

$sql = "SELECT * FROM tasks";
$r = mysql_query($sql, $conn);
$arr = array();
while ($row = mysql_fetch_assoc($r))
   $arr[] = $row

function build($arrayIn, $parent)
{
    $makeFilter = function($p) {return function($x) use ($p) {return $x['parent'] == $p;};};
    $f = $makeFilter($parent);
    $these = array_filter($arrayIn, $f);
    $remaining = array_diff_assoc($arrayIn, $these);
    $ans = array();

    foreach($these as $cur)
    {
       $ans[$cur['text']] = build($remaining, $cur['id']);
    }
    return $ans ? $ans : null;
}

$tree = build($arr, 0)
echo_r($arr);
echo "becomes<br />";
echo_r($tree);

这是我的输出:

Array
(
[0] => Array
    (
        [text] => a
        [id] => 1
        [parent] => 0
    )

[1] => Array
    (
        [text] => b
        [id] => 2
        [parent] => 0
    )

[2] => Array
    (
        [text] => c
        [id] => 3
        [parent] => 1
    )

[3] => Array
    (
        [text] => d
        [id] => 4
        [parent] => 2
    )

[4] => Array
    (
        [text] => e
        [id] => 5
        [parent] => 2
    )

[5] => Array
    (
        [text] => f
        [id] => 6
        [parent] => 3
    )

)

becomes

Array
(
[a] => Array
    (
        [c] => Array
            (
                [f] => 
            )

    )

[b] => Array
    (
        [d] => 
        [e] => 
    )

)

【讨论】:

    【解决方案2】:

    这段伪代码应该会有所帮助。

    函数 getTasks($parent = 0){
        $tasks = 数组();
        $query = mysql_query("select * from table where parent = $parent");
        $rows = 数组();
        while(($row = mysql_fetch_assoc($query)) !== FALSE){ $rows[] = $row; }
        如果(计数($行)){
            $tasks[$parent][] = getTasks($parent);
        } 别的 {
            返回$任务;
        }
    }
    
    $tasks = getTasks();

    【讨论】:

      【解决方案3】:

      这里你真的不需要递归函数。使用一个数据库查询获取所有数据并对其进行循环。它会比多个数据库调用快得多。

      假设您将数据存储在 MySQL 中,see the answer to this question for instructions on how to write a SELECT statement against an Adjacency List table that returns everything in a hierarchy。简而言之,使用 MySQL 会话变量。然后获取结果集并对其进行循环,使用堆栈来推送 - 弹出 - 查看最后一个父 id 以确定数据结构的缩进。

      【讨论】:

        【解决方案4】:

        这是我为处理各种邻接列表任务而编写的一个 PHP 类。

        http://www.pdvictor.com/?sv=&category=just+code&title=adjacency+model

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-02-20
          • 2020-07-19
          • 2011-11-23
          • 1970-01-01
          • 1970-01-01
          • 2017-06-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多