function cat_options($spec_cat_id, $arr){static $cat_options = array();if (isset($cat_options[$spec_cat_id])){ return $cat_options[$spec_cat_id];}/*初期化キーパラメータ: $level: 現在の子ノードの深さ $last_cat_id: 現在の親ノード ID $options: インデントレベルの配列 $cat_id_array: 沿った親ノード同じパスが順番に配置されます $level_array: このノードの子ノードの深さも順番に配置されます */if (!isset($cat_options[0])){$level = $last_cat_id = 0; $options = $cat_id_array = $level_array = array();while (!empty($arr))//構築すべきノードがまだある場合は、走査を続行します{foreach ($arr AS $key = > $value) { $cat_id = $value['cat_id']; //レベル 1 分類ノード if ($level == 0 && $last_cat_id == 0) { if ($value[' parent_id'] > 0) { break; } $options[$cat_id] = $value; $options[$cat_id]['level'] = $level; $options[$cat_id][' id'] = $cat_id; $options[$cat_id]['name'] = $value['cat_name']; //一度走査された後は走査されなくなります unset($arr[$key] ]); if ($value ['has_children'] == 0) { Continue; } $last_cat_id = $cat_id;//下位ノードの親ノード $cat_id_array = array($cat_id); $level_array[$last_cat_id] = ++$level; Continue; } //現在のノードの親ノードIDは上位ノードIDと等しい if ($value['parent_id'] == $last_cat_id) { $options [$cat_id] = $value; $options[$cat_id]['level'] = $level; $options[$cat_id]['id'] = $cat_id; $ options[$cat_id]['name '] = $value['cat_name']; unset($arr[$key]);//走査後は走査されなくなります //現在のノードに子がある場合、現在のノードは配置されますが、トラバースしなくなります。それ以外の場合は、 if ($value['has_children'] > 0) { if (end($cat_id_array) != $last_cat_id を入力しないとトラバースされません) ) { $cat_id_array[] = $last_cat_id; } $last_cat_id = $cat_id;//現在のノードが次のレベルのノードの新しい親ノードとして使用される場合 $cat_id_array[] = $cat_id;/ /Enter $ level_array[$last_cat_id] = ++$level;//現在のノードの次のレベルのノードの深さ } } elseif ($value['parent_id'] > $last_cat_id ) {//現在のノードの親の深さが現在の親ノードの深さよりも大きい場合は、次のサイクルに進みます break; } }/ /endforeach $count = count($cat_id_array); if ($count > ; 1) { //最後に入力した親ノードを現在の親ノードとして取り出します $last_cat_id = array_pop($cat_id_array); } elseif ($count == 1) { if ($last_cat_id != end( $cat_id_array)) { //常駐親ノードが1つしかなく、それが現在の親ノードとして使用されていない場合は、それを取得out $last_cat_id = end($cat_id_array); } else { //それ以外の場合は、最後の親が取り出されます ノードは第 1 レベルの分類ノードでなければなりません $level = 0; $last_cat_id = 0; $ cat_id_array = array(); continue; } } if ($last_cat_id && isset($level_array[$last_cat_id])) { // 現在のノードの深さを取得する $level = $level_array[$last_cat_id]; } else { $level = 0; } }//end 一方、この時点では、ツリーを構築するための非再帰的事前順序トラバーサルの作業が行われます。 $options がルート ノードから始まるすべてのノードの階層配列を保存しました $cat_options[0] = $options } else { $options = $cat_options[0]; } //ツリー全体が 0 から開始される場合は、直接返され、処理されなくなります。 if (!$spec_cat_id) { return $options; //それ以外の場合は、指定されたノードからインターセプトを開始します。以下は比較的単純です。いくつかのパラメーターの意味について説明します。 /* $spec_cat_id_level: インターセプトされたノードの深さ $spec_cat_id_array: 製品分類ツリー。このノードをルート ノードとして使用します 最終的に返される配列は、親ノードのサイズ、直接の親ノード、同じ親ノードなどによって並べ替えられます。 例: 第 1 レベルのノードは次のようになります。 1,5 の場合、第 2 レベルのノードは 2,6,7 になり、第 3 レベルのノードは 8,9 になります。1 の直接の子が 2,6 で、さらに 2 の直接の子が 8,9 になります。 5 の直接の子は 7 です。すると、最終的な配列は次のように配置されます 1->2->8->9->6->5->7 */ else { if ( empty($options[$spec_cat_id])) { return array(); } $spec_cat_id_level = $options[$spec_cat_id]['level']; foreach ( $options AS $key => $value) { if ($key != $spec_cat_id) { unset($options[$key]); } else { break; } } $spec_cat_id_array = array(); foreach ($options AS $key => $value) { if (($spec_cat_id_level == $value['level'] && $value['cat_id'] != $spec_cat_id ) | ($spec_cat_id_level > $value['level'])) { break; } else { $spec_cat_id_array[$key] = $value; } } $cat_options[$spec_cat_id ] = $spec_cat_id_array; return $spec_cat_id_array; } } ?> コードをコピー