4

我已经为这样的问题奋斗了几个小时。为了加快我的网页速度,我请求数据库一次获取所有类别,然后想使用 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] => 
                  )
        )

)

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

4

5 回答 5

4

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

例如:

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

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

  3. 编写一个递归存储过程,它返回按深度优先树遍历排序的结果集

以示例 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
于 2011-01-31T17:41:06.750 回答
0
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;
}

这期望父母总是在其孩子之前被填充

于 2011-01-31T17:20:31.300 回答
0

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

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

于 2011-01-31T17:21:36.860 回答
0

您正在寻找的是所谓的递归,就我而言,如何处理 php 中的递归并不是很清楚,关于这个主题的文档几乎是空白的。

你可能有兴趣查看这个这篇文章

于 2011-01-31T17:58:37.430 回答
0

不确定您是否找到了答案,但我今天一直在寻找相同的解决方案,最后最终制定了自己的解决方案。下面的代码是我刚刚创建的类,它适用于 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 '&emsp;';
        }
    }
}

# 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;
}
}

?>
于 2014-03-07T18:06:03.417 回答