循环地在 PHP 数组中创建层次结构

发布于 2024-10-15 01:45:32 字数 841 浏览 9 评论 0原文

我已经和这样的问题斗争了几个小时了。为了加快我的网页速度,我请求数据库一次获取所有类别,然后想使用 PHP 对数组进行排序。

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => name1
            [parent] => 0
            [children] => 
        )
   [1] => Array
    (
        [id] => 2
        [name] => name2
        [parent] => 1
        [children] => 
    )
)

我需要得到这样的东西,

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => name1
            [parent] => 0
            [children] => Array
                  (
                      [id] => 2
                      [name] => name2
                      [parent] => 1
                      [children] => 
                  )
        )

)

问题是使它适用于任何层次结构。这样就可以循环工作了。请帮忙!

I've been fighting for hours with such a problem. For speeding my web-page I request database to get all categories just one time and then want to sort the array using PHP.

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => name1
            [parent] => 0
            [children] => 
        )
   [1] => Array
    (
        [id] => 2
        [name] => name2
        [parent] => 1
        [children] => 
    )
)

I need to get something like this

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => name1
            [parent] => 0
            [children] => Array
                  (
                      [id] => 2
                      [name] => name2
                      [parent] => 1
                      [children] => 
                  )
        )

)

The problem with that is making it for any level of hierarchy. So that it could work in cycle. Please help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

浅沫记忆 2024-10-22 01:45:32

有很多解决方案可以减少这里的开销。但如果不知道您的限制是什么,就很难推荐一种方法。

例如:

  1. 使用邻接模型 - 请参阅我对 dnagirl 的答案的评论

  2. 将所有数据加载到 PHP 中,然后使用递归算法创建嵌套树(这会相当慢,并且会受益于一些缓存)

  3. write返回按深度优先树遍历排序的结果集的递归存储过程

以示例 2 为例,更接近代码... .像...之类的东西

 function build_tree(&$unsorted, $start_node)
 {
     $out=array();
     foreach($unsorted as $key=>$node) {
        if ($node['parent']==$start_node) {
            $node['children']=build_tree($unsorted, $key);
            unset($unsorted[$key]);
            $out[]=$node;
        }
     }
     return $out;
 } 
 $threaded_tree=build_tree($list_of_nodes, 0); // assumes that the root is the first element

There are lots of solutions to reducing the overhead here. But without knowing what your constraints are, it's difficult to recommend an approach.

e.g.:

  1. use an adjacency model - see my comment on dnagirl's answer

  2. load all the data into PHP then use a recursion algorithm to create the nested tree (this will be rather slow and would benefit from some caching)

  3. write a recursive stored procedure which returns the result set sorted by a depth-first tree walk

Taking example 2 a bit closer to code....something like....

 function build_tree(&$unsorted, $start_node)
 {
     $out=array();
     foreach($unsorted as $key=>$node) {
        if ($node['parent']==$start_node) {
            $node['children']=build_tree($unsorted, $key);
            unset($unsorted[$key]);
            $out[]=$node;
        }
     }
     return $out;
 } 
 $threaded_tree=build_tree($list_of_nodes, 0); // assumes that the root is the first element
鹤仙姿 2024-10-22 01:45:32

您正在为层次结构使用邻接模型。您必须多次查询数据库,或者如果级别数已知,则为每个级别构造一个带有子句的联合查询。

如果允许,您可能会发现单击父级时调用子级的 AJAX 解决方案既更容易编程,也更高效。

You're using an adjacency model for your hierarchy. You will either have to query your db multiple times, or if the number of levels is known, construct a union query with a clause for each level.

If it is allowed, you'll likely find that an AJAX solution where child levels are called when the parent is clicked is both easier to program and more efficient.

风月客 2024-10-22 01:45:32
foreach ($dataFromMySQL as $e) {
    $all[$e['id']] = $e;
    $ref = &$all[$e['id'];
    if ($e['parent']) $all[$e['id']]['children'][] = $ref;
    else $hierarchy[$e['id']] = $ref;
}

这期望父母总是先于孩子被填充

foreach ($dataFromMySQL as $e) {
    $all[$e['id']] = $e;
    $ref = &$all[$e['id'];
    if ($e['parent']) $all[$e['id']]['children'][] = $ref;
    else $hierarchy[$e['id']] = $ref;
}

This expects parents to always be populated before its children

笑梦风尘 2024-10-22 01:45:32

你正在寻找的是所谓的递归,对我来说,它不是很清楚如何在 php 中处理递归,并且关于这个主题的文档几乎是空白的。

您可能有兴趣查看这篇文章

What you are looking for is called recursion, as for me it is not very clear how to handle recursions in php and documentation is almost blank regarding this subject.

You might be interested to check this and this article

青芜 2024-10-22 01:45:32

不确定您是否找到了答案,但我今天一直在寻找相同的解决方案,最后最终制定了自己的解决方案。下面的代码是我刚刚创建的类,它适用于 PHP 数组和对象,并且递归到无限数量的维度。

GitHub https://github.com/DukeOfMarshall/PHP-Array -Heirarchy-Display

使用此代码的一个简单示例是:

<?php

require_once('Arrays.class.php');
$display = new Array_Functions();

$display->display_hierarchy($multidimensional_array);

?>

还可以设置其他选项,但这只是数组或对象的直接层次结构显示。

<?php

class Array_Functions {
public $number_of_tabs  = 3; # The default number of tabs to use when branching out
private $counter            = 0; # The counter to use for the number of tab iterations to use on the current branch

public $display_square_brackets     = TRUE; 
public $display_squiggly_brackets = FALSE;
public $display_parenthesis           = FALSE;

public $display_apostrophe  = TRUE;
public $display_quotes        = FALSE;

public function __construct(){
}

/**
 * Displays the array in an organized heirarchy and even does so recursively
 * 
 * $array ARRAY - The array to display in a heirarchy
 * 
 * $key_bookends STRING - The character to place on either side of the array key when printed
 * @@ square - Displays a set of square brackets around the key (DEFAULT)
 * @@ squiggly - Displays a set of squiggly brackets around the key
 * @@ parenthesis - Displays a set of parenthesis around the key
 * @@ FALSE - Turns off the display of bookends around the array key
 * 
 * $key_padding STRING - The padding to use around the array key with printed
 * @@ quotes - Pads the array key with double quotes when printed
 * @@ apostrophe - Pads the array key with apostrophes when printed (DEFAULT)
 * @@ FALSE - Turns off the display of padding around the array key
 * 
 * $number_of_tabs_to_use INT - The number of tabs to use when a sub array within the array creates a branch in the heirarchy
 * 
 */
public function display_hierarchy($array, $key_bookends = '', $key_padding = '', $number_of_tabs_to_use = ''){
    # Convert the input to a JSON and then back to an array just to make sure we know what we're working with
    $array = $this->convert_object_to_array($array);

    # If the $array variable is still not an array, then error out.
    # We're not going to fool around with your stupidity
    if(gettype($array) != 'array'){
        echo 'Value submitted was '.strtoupper(gettype($array)).' instead of ARRAY or OBJECT. Only arrays or OBJECTS are allowed Terminating execution.';
        exit();
    }

    # Establish the bookend variables
    if($key_bookends != '' || !$key_bookends){
        if(strtolower($key_bookends) == 'square'){
            $this->display_square_brackets      = TRUE;
            $this->display_squiggly_brackets    = FALSE;
            $this->display_parenthesis            = FALSE;
        }elseif(strtolower($key_bookends) == 'squiggly'){
            $this->display_square_brackets      = TRUE;
            $this->display_squiggly_brackets    = TRUE;
            $this->display_parenthesis            = FALSE;
        }elseif(strtolower($key_bookends) == 'parenthesis'){
            $this->display_square_brackets      = FALSE;
            $this->display_squiggly_brackets    = FALSE;
            $this->display_parenthesis          = TRUE;
        }elseif(!$key_bookends){
            $this->display_square_brackets      = FALSE;
            $this->display_squiggly_brackets    = FALSE;
            $this->display_parenthesis            = FALSE;
        }
    }


    # Establish the padding variables
    if($key_padding != '' || !$key_padding){
        if(strtolower($key_padding) == 'apostrophe'){
            $this->display_apostrophe = TRUE;
            $this->display_quotes       = FALSE;
        }elseif(strtolower($key_padding) == 'quotes'){
            $this->display_apostrophe = FALSE;
            $this->display_quotes       = TRUE;
        }elseif(!$key_padding){
            $this->display_apostrophe = FALSE;
            $this->display_quotes       = FALSE;
        }
    }       

    # Establish variable for the number of tabs
    if(isset($number_of_tabs_to_use) && $number_of_tabs_to_use != ''){
        $this->number_of_tabs = $number_of_tabs_to_use;
    }

    foreach($array as $key => $value){
        $this->insert_tabs();

        if(is_array($value)){
            echo $this->display_padding($key)." => {<BR>";

            $this->counter++;
            $this->display_hierarchy($value);
            $this->counter--;
            $this->insert_tabs();
            echo '} <BR>';
        }else{
            echo $this->display_padding($key)." => ".$value.'<BR>';
        }
    }
}

# Inserts tab spaces for sub arrays when a sub array triggers a branch in the heirarchy
# Helps to make the display more human readable and easier to understand
private function insert_tabs(){
    for($i=1; $i<=$this->counter; $i++){
        for($x=1; $x<=$this->number_of_tabs; $x++){
            echo ' ';
        }
    }
}

# Takes a PHP object and converts it to an array
# Works with single dimension and multidimensional arrays
public function convert_object_to_array($object){
    $object = json_decode(json_encode($object), TRUE);
    return $object;
}

# Sets the displayed padding around the array keys when printed on the screen
public function display_padding($value){
    $default_container = "['VALUE_TO_REPLACE']";

    $value = str_replace("VALUE_TO_REPLACE", $value, $default_container);

    if($this->display_square_brackets){
    }elseif($this->display_squiggly_brackets){
        $value = str_replace('[', '{', $value);
        $value = str_replace(']', '}', $value);
    }elseif($this->display_parenthesis){
        $value = str_replace('[', '(', $value);
        $value = str_replace(']', ')', $value);
    }else{
        $value = str_replace('[', '', $value);
        $value = str_replace(']', '', $value);
    }

    if($this->display_apostrophe){
    }elseif($this->display_quotes){
        $value = str_replace("'", '"', $value);
    }else{
        $value = str_replace("'", '', $value);
    }

    return $value;
}
}

?>

Not sure if you've found an answer yet, but I was looking for the same solution today and finally ended up making my own solution. The below code is the class I just created and it works with PHP arrays and objects and is recursive to an unlimited number of dimensions.

GitHub https://github.com/DukeOfMarshall/PHP-Array-Heirarchy-Display

A simple example of using this code would be:

<?php

require_once('Arrays.class.php');
$display = new Array_Functions();

$display->display_hierarchy($multidimensional_array);

?>

There are other options that can be set as well, but that was just a straight up heirarchal display of an array or object.

<?php

class Array_Functions {
public $number_of_tabs  = 3; # The default number of tabs to use when branching out
private $counter            = 0; # The counter to use for the number of tab iterations to use on the current branch

public $display_square_brackets     = TRUE; 
public $display_squiggly_brackets = FALSE;
public $display_parenthesis           = FALSE;

public $display_apostrophe  = TRUE;
public $display_quotes        = FALSE;

public function __construct(){
}

/**
 * Displays the array in an organized heirarchy and even does so recursively
 * 
 * $array ARRAY - The array to display in a heirarchy
 * 
 * $key_bookends STRING - The character to place on either side of the array key when printed
 * @@ square - Displays a set of square brackets around the key (DEFAULT)
 * @@ squiggly - Displays a set of squiggly brackets around the key
 * @@ parenthesis - Displays a set of parenthesis around the key
 * @@ FALSE - Turns off the display of bookends around the array key
 * 
 * $key_padding STRING - The padding to use around the array key with printed
 * @@ quotes - Pads the array key with double quotes when printed
 * @@ apostrophe - Pads the array key with apostrophes when printed (DEFAULT)
 * @@ FALSE - Turns off the display of padding around the array key
 * 
 * $number_of_tabs_to_use INT - The number of tabs to use when a sub array within the array creates a branch in the heirarchy
 * 
 */
public function display_hierarchy($array, $key_bookends = '', $key_padding = '', $number_of_tabs_to_use = ''){
    # Convert the input to a JSON and then back to an array just to make sure we know what we're working with
    $array = $this->convert_object_to_array($array);

    # If the $array variable is still not an array, then error out.
    # We're not going to fool around with your stupidity
    if(gettype($array) != 'array'){
        echo 'Value submitted was '.strtoupper(gettype($array)).' instead of ARRAY or OBJECT. Only arrays or OBJECTS are allowed Terminating execution.';
        exit();
    }

    # Establish the bookend variables
    if($key_bookends != '' || !$key_bookends){
        if(strtolower($key_bookends) == 'square'){
            $this->display_square_brackets      = TRUE;
            $this->display_squiggly_brackets    = FALSE;
            $this->display_parenthesis            = FALSE;
        }elseif(strtolower($key_bookends) == 'squiggly'){
            $this->display_square_brackets      = TRUE;
            $this->display_squiggly_brackets    = TRUE;
            $this->display_parenthesis            = FALSE;
        }elseif(strtolower($key_bookends) == 'parenthesis'){
            $this->display_square_brackets      = FALSE;
            $this->display_squiggly_brackets    = FALSE;
            $this->display_parenthesis          = TRUE;
        }elseif(!$key_bookends){
            $this->display_square_brackets      = FALSE;
            $this->display_squiggly_brackets    = FALSE;
            $this->display_parenthesis            = FALSE;
        }
    }


    # Establish the padding variables
    if($key_padding != '' || !$key_padding){
        if(strtolower($key_padding) == 'apostrophe'){
            $this->display_apostrophe = TRUE;
            $this->display_quotes       = FALSE;
        }elseif(strtolower($key_padding) == 'quotes'){
            $this->display_apostrophe = FALSE;
            $this->display_quotes       = TRUE;
        }elseif(!$key_padding){
            $this->display_apostrophe = FALSE;
            $this->display_quotes       = FALSE;
        }
    }       

    # Establish variable for the number of tabs
    if(isset($number_of_tabs_to_use) && $number_of_tabs_to_use != ''){
        $this->number_of_tabs = $number_of_tabs_to_use;
    }

    foreach($array as $key => $value){
        $this->insert_tabs();

        if(is_array($value)){
            echo $this->display_padding($key)." => {<BR>";

            $this->counter++;
            $this->display_hierarchy($value);
            $this->counter--;
            $this->insert_tabs();
            echo '} <BR>';
        }else{
            echo $this->display_padding($key)." => ".$value.'<BR>';
        }
    }
}

# Inserts tab spaces for sub arrays when a sub array triggers a branch in the heirarchy
# Helps to make the display more human readable and easier to understand
private function insert_tabs(){
    for($i=1; $i<=$this->counter; $i++){
        for($x=1; $x<=$this->number_of_tabs; $x++){
            echo ' ';
        }
    }
}

# Takes a PHP object and converts it to an array
# Works with single dimension and multidimensional arrays
public function convert_object_to_array($object){
    $object = json_decode(json_encode($object), TRUE);
    return $object;
}

# Sets the displayed padding around the array keys when printed on the screen
public function display_padding($value){
    $default_container = "['VALUE_TO_REPLACE']";

    $value = str_replace("VALUE_TO_REPLACE", $value, $default_container);

    if($this->display_square_brackets){
    }elseif($this->display_squiggly_brackets){
        $value = str_replace('[', '{', $value);
        $value = str_replace(']', '}', $value);
    }elseif($this->display_parenthesis){
        $value = str_replace('[', '(', $value);
        $value = str_replace(']', ')', $value);
    }else{
        $value = str_replace('[', '', $value);
        $value = str_replace(']', '', $value);
    }

    if($this->display_apostrophe){
    }elseif($this->display_quotes){
        $value = str_replace("'", '"', $value);
    }else{
        $value = str_replace("'", '', $value);
    }

    return $value;
}
}

?>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文