2011-01-31 123 views
4

我一直在为这样一个问题奋斗了几个小时。为了加速我的网页,我要求数据库只获得一次所有类别,然后想要使用PHP对数组进行排序。在循环中创建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] => 
       ) 
     ) 

) 

但问题是使其成为层次结构的任何水平。以便它可以循环工作。请帮忙!

回答

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

这种预期的父母总是被它的孩子

+0

像什么样的数据库结构,我应该适应它最好? – user597214 2011-01-31 17:30:22

+0

我以为你已经有一个数据库结构...你得到的结构很好。根据您存储/显示的信息@dnagirl可能是正确的... Ajax可能会更好。如果你一次需要所有的信息 - 使用你上面提到的人口方法提出的数据库结构。 – Mikhail 2011-01-31 17:38:01

0

之前,您使用的邻接模型层次结构填充。您将不得不多次查询您的数据库,或者如果已知级别的数量,请使用每个级别的子句构造一个联合查询。

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

+0

所以什么是最好的方式来存储层次结构在数据库中没有这样的问题& – user597214 2011-01-31 17:29:22

+0

实际上这是父引用 - 不是邻接 - 请参阅http://articles.sitepoint.com/article/hierarchical-data-database有关邻接的描述模型。 – symcbean 2011-01-31 17:29:23

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 
0

你所寻找被称为递归,因为对我来说不是很清楚如何处理关于这个主题,php和文档中的递归几乎是空白的。

您可能会感兴趣检查thisthis文章

0

不知道如果你找到一个答案了,但今天我一直在寻找相同的解决方案,并最终最终使自己的解决方案。下面的代码是我刚刚创建的类,它适用于PHP数组和对象,并递归到无限数量的维度。

GitHubhttps://github.com/DukeOfMarshall/PHP-Array-Heirarchy-Display

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

<?php 

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

$display->display_hierarchy($multidimensional_array); 

?> 

有可以设置以及其他选项,但这是一个阵列的只是一个直线上升heirarchal显示或对象。

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

?>