簡単に言うと、Infinitus 分類とは、Windows が新しいフォルダーを作成し、このフォルダー内にいくつかのフォルダーを作成したり、そのフォルダーの下にいくつかのフォルダーを作成したりすることもできます。
それでは、PHP はどのようにして無限の分類を実現するのでしょうか?さまざまなカテゴリを 1 つずつリストするにはどうすればよいでしょうか?
まず、このような配列があると仮定しましょう
$arr = array( 0=>array( 'cid'=>1, 'pid'=>0, 'name'=>'亚洲', ), 1=>array( 'cid'=>2, 'pid'=>0, 'name'=>'北美洲', ), 2=>array( 'cid'=>3, 'pid'=>1, 'name'=>'中国', ), 3=>array( 'cid'=>4, 'pid'=>2, 'name'=>'美国', ), 4=>array( 'cid'=>5, 'pid'=>3, 'name'=>'北京', ), 5=>array( 'cid'=>6, 'pid'=>3, 'name'=>'河北', ), 6=>array( 'cid'=>7, 'pid'=>5, 'name'=>'东城区', ), 7=>array( 'cid'=>8, 'pid'=>5, 'name'=>'海淀区', ), );
写真に示すように、これと同様の表示が必要です
この配列を上の画像のように直感的に表示したい場合は、次のようにする必要がありますphp を使用して再帰的に実現するには、どのように実装すればよいでしょうか?以下のコアコードを見てください
コードをコピーしてください
private function GetTree($arr,$pid,$step){ global $tree; foreach($arr as $key=>$val) { if($val['pid'] == $pid) { $flg = str_repeat('└―',$step); $val['name'] = $flg.$val['name']; $tree[] = $val; $this->GetTree($arr , $val['cid'] ,$step+1); } } return $tree; }
コードをコピーしてください
その後、必要なのは呼び出しコードを書くだけです
$newarr = $this->GetTree($arr, 0, 0);
サブクラスIDに基づいてすべての親分類情報を見つけます(yii2フレームワーク内)
メソッド1:
public static function get_parent_list($arr,$id){ //$arr 所有分类列表 //$id 父级分类id static $list=array(); foreach($arr as $u){ if($u['id']== $id){//父级分类id等于所查找的id $list[]=$u; if($u['parent_id']>0){ self::get_parent_list($arr,$u['parent_id']); } } } return $list; }
このようにして、再帰クエリを行わずに分類情報をキャッシュに保存できます。
方法 2: 分類情報を取得するための再帰クエリ
public static function get_parents($id){ static $list = []; $cat_data = Category::findOne($id)->toarray(); if($cat_data){ $list[] = $cat_data; $id = $cat_data['parent_id']; if($cat_data['parent_id'] > 0){ self::get_parents($id); } } return $list; }
無限の分類を達成する必要があるため、そのサブ列が何であるかを知る必要があります。
最終的に実装される配列は次の形式になります:
[php] view plain copyArray ( [0] => Array ( [category_id] => 1 [category_name] => 关于我 [category_pid] => 0 [category_addtime] => 0 [category_order] => 0 ) [1] => Array ( [category_id] => 2 [category_name] => 生活随笔 [category_pid] => 0 [category_addtime] => 0 [category_order] => 0 ) [2] => Array ( [category_id] => 3 [category_name] => 文章类别 [category_pid] => 0 [category_addtime] => 0 [category_order] => 0 [category_child] => Array ( [0] => Array ( [category_id] => 4 [category_name] => Linux服务器 [category_pid] => 3 [category_addtime] => -28800 [category_order] => 1 [category_child] => Array ( [0] => Array ( [category_id] => 5 [category_name] => linux优化 [category_pid] => 4 [category_addtime] => 0 [category_order] => 0 ) [1] => Array ( [category_id] => 6 [category_name] => 虚拟化 [category_pid] => 4 [category_addtime] => 1478228220 [category_order] => 0 ) [2] => Array ( [category_id] => 7 [category_name] => Mysql优化与开发 [category_pid] => 4 [category_addtime] => 1478188800 [category_order] => 0 ) [3] => Array ( [category_id] => 8 [category_name] => 高可用与虚拟化 [category_pid] => 4 [category_addtime] => 1478394120 [category_order] => 0 ) ) ) [1] => Array ( [category_id] => 15 [category_name] => Mysql [category_pid] => 3 [category_addtime] => 1480555980 [category_order] => 0 [category_child] => Array ( [0] => Array ( [category_id] => 16 [category_name] => 优化 [category_pid] => 15 [category_addtime] => 1480555980 [category_order] => 0 ) [1] => Array ( [category_id] => 17 [category_name] => Sql编程 [category_pid] => 15 [category_addtime] => 1480556040 [category_order] => 8 ) ) ) ) ) )
それでは、データベースから取り出した 2 次元配列はどのようにして上記のような配列になるのでしょうか?
例:
上記のフォームに次の 2 次元配列を実装したいとします。
[php] view plain copy
$arr=array( array('id'=>'1','name'=>'北京','pid'=>'0'), array('id'=>'2','name'=>'上海','pid'=>'0'), array('id'=>'3','name'=>'浦东','pid'=>'2'), array('id'=>'4','name'=>'朝阳','pid'=>'1'), array('id'=>'5','name'=>'广州','pid'=>'0'), array('id'=>'6','name'=>'三里屯','pid'=>'4'), array('id'=>'7','name'=>'广东','pid'=>'5'), array('id'=>'8','name'=>'三里','pid'=>'4'), array('id'=>'10','name'=>'小胡同','pid'=>'8') );
最初の方法: 主キーの ID 番号と同じになる配列のインデックスを使用して、最初に配列にインデックスを追加します:
[php] view plain copy
$arr=array( 1=>array('id'=>'1','name'=>'北京','pid'=>'0'), 2=>array('id'=>'2','name'=>'上海','pid'=>'0'), 3=>array('id'=>'3','name'=>'浦东','pid'=>'2'), 4=>array('id'=>'4','name'=>'朝阳','pid'=>'1'), 5=>array('id'=>'5','name'=>'广州','pid'=>'0'), 6=>array('id'=>'6','name'=>'三里屯','pid'=>'4'), 7=>array('id'=>'7','name'=>'广东','pid'=>'5'), 8=>array('id'=>'8','name'=>'三里','pid'=>'4'), 10=>array('id'=>'10','name'=>'小胡同','pid'=>'8') );
使用 カラムに親カラムがあるかどうかを判断するためにインデックスの添字が使用されます。親カラムが存在する場合、そのカラムを親カラムのson配列に入れます
[php] view plain copy
function generateTree($items){ $tree = array(); foreach($items as $item){ //判断是否有数组的索引== if(isset($items[$item['pid']])){ //查找数组里面是否有该分类 如 isset($items[0]) isset($items[1]) $items[$item['pid']]['son'][] = &$items[$item['id']]; //上面的内容变化,$tree里面的值就变化 }else{ $tree[] = &$items[$item['id']]; //把他的地址给了$tree } } return $tree; }
上記のプログラムには大きな問題があります。配列のインデックスは手動で追加しましたか?では、配列インデックスを自動的に追加できるでしょうか?もちろん、配列にインデックスを自動的に追加し、親列の子配列にサブ列を配置する次のプログラムも実装できます。考え方は上記のプログラムと同じです
[php] view plain copy
function make_tree($list,$pk='id',$pid='pid',$child='_child',$root=0){ $tree=array(); $packData=array(); foreach ($list as $data) { <span style="white-space:pre"> </span>//转换为带有主键id的数组 $packData[$data[$pk]] = $data; //$packData[1]=$data; $packData[2]=$data } foreach ($packData as $key =>$val){ if($val[$pid]==$root){ //代表跟节点 $tree[]=& $packData[$key]; }else{ //找到其父类 $packData[$val[$pid]][$child][]=& $packData[$key]; } } return $tree; }
Second 別の方法: 再帰を使用してサブ列を検索します
アイデア: 再帰を使用して各列のサブ列を検索し、最後のサブ列が見つかるまで、レイヤーごとにデバッグを実行します。それをツリー内に表示します
、理解を容易にするために、 $tree を出力して配列内の変更を観察できます
[php] プレーンコピーを表示します
array('id'=>'6','name'=>'三里屯','pid'=>'4'), [php] view plain copyfunction make_tree1($list,$pk='id',$pid='pid',$child='_child',$root=0){ $tree=array(); foreach($list as $key=> $val){ if($val[$pid]==$root){ //获取当前$pid所有子类 unset($list[$key]); if(! empty($list)){ $child=make_tree1($list,$pk,$pid,$child,$val[$pk]); //来来来 找北京的子栏目 递归 空 if(!empty($child)){ $val['_child']=$child; } } $tree[]=$val; } } return $tree; }
再帰をよりよく理解するために、次のようにすることができます次の合計プログラムのような、テストする小さなプログラムを見つけてください
全員 このプログラムから、$n の出力を 10, 9--2 からではなく、2, 3...10 から分析できます。上記のプログラムの再帰が実装されています。つまり、再帰は非常に興味深いものです。皆さんにもよく理解していただければ幸いです
[php] プレーンコピーを表示
function sum($n){ $a=0; if($n>1){ $a=sum($n-1)+$n; /*if($n>5){ echo "$n <br />" ; }*/ echo "$n<br />"; }else{ $a=1; } return $a; } echo sum(10);
親 id
#$id = 父级id, $array = 所有分类public function getSon($id,$array){ static $list; foreach ($array as $k => $v) { if($v['parent_id'] == $id){ $list[] = $array[$k]; self::getSon($v['id'],$array); } } return $list; }
php Infinitus 分類
まず Infinite Extreme 分類とは何なのかを紹介します。
簡単に言うと、Infinitus 分類とは、Windows が新しいフォルダーを作成してから別のフォルダーを作成できるのと同じように、カテゴリを複数のサブカテゴリに分割し、さらに 1 つのサブカテゴリを他の複数のサブカテゴリに分割するなど、無限に分割できることを意味します。このフォルダー内にいくつかのフォルダーを作成することも、そのフォルダーの下にいくつかのフォルダーを作成することもできます
では、PHP はどのようにして無限の分類を実現するのでしょうか?さまざまなカテゴリを 1 つずつリストするにはどうすればよいでしょうか?
まず、このような配列があると仮定しましょう
$arr = array( 0=>array( 'cid'=>1, 'pid'=>0, 'name'=>'亚洲', ), 1=>array( 'cid'=>2, 'pid'=>0, 'name'=>'北美洲', ), 2=>array( 'cid'=>3, 'pid'=>1, 'name'=>'中国', ), 3=>array( 'cid'=>4, 'pid'=>2, 'name'=>'美国', ), 4=>array( 'cid'=>5, 'pid'=>3, 'name'=>'北京', ), 5=>array( 'cid'=>6, 'pid'=>3, 'name'=>'河北', ), 6=>array( 'cid'=>7, 'pid'=>5, 'name'=>'东城区', ), 7=>array( 'cid'=>8, 'pid'=>5, 'name'=>'海淀区', ), );
写真に示すように、これと同様の表示が必要です
この配列を上の画像のように直感的に表示したい場合は、次のようにする必要がありますphp を使用して再帰的に実現するには、どのように実装すればよいでしょうか?以下のコアコードを見てください
コードをコピーしてください
private function GetTree($arr,$pid,$step){ global $tree; foreach($arr as $key=>$val) { if($val['pid'] == $pid) { $flg = str_repeat('└―',$step); $val['name'] = $flg.$val['name']; $tree[] = $val; $this->GetTree($arr , $val['cid'] ,$step+1); } } return $tree; }
コードをコピーしてください
その後、必要なのは呼び出しコードを書くだけです
$newarr = $this->GetTree($arr, 0, 0);
サブクラスIDに基づいてすべての親分類情報を見つけます(yii2フレームワーク内)
メソッド1:
public static function get_parent_list($arr,$id){ //$arr 所有分类列表 //$id 父级分类id static $list=array(); foreach($arr as $u){ if($u['id']== $id){//父级分类id等于所查找的id $list[]=$u; if($u['parent_id']>0){ self::get_parent_list($arr,$u['parent_id']); } } } return $list; }
このようにして、再帰クエリを行わずに分類情報をキャッシュに保存できます。
方法 2: 分類情報を取得するための再帰クエリ
public static function get_parents($id){ static $list = []; $cat_data = Category::findOne($id)->toarray(); if($cat_data){ $list[] = $cat_data; $id = $cat_data['parent_id']; if($cat_data['parent_id'] > 0){ self::get_parents($id); } } return $list; }
無限の分類を達成する必要があるため、そのサブ列が何であるかを知る必要があります。
最終的に実装される配列は次の形式になります:
[php] view plain copyArray ( [0] => Array ( [category_id] => 1 [category_name] => 关于我 [category_pid] => 0 [category_addtime] => 0 [category_order] => 0 ) [1] => Array ( [category_id] => 2 [category_name] => 生活随笔 [category_pid] => 0 [category_addtime] => 0 [category_order] => 0 ) [2] => Array ( [category_id] => 3 [category_name] => 文章类别 [category_pid] => 0 [category_addtime] => 0 [category_order] => 0 [category_child] => Array ( [0] => Array ( [category_id] => 4 [category_name] => Linux服务器 [category_pid] => 3 [category_addtime] => -28800 [category_order] => 1 [category_child] => Array ( [0] => Array ( [category_id] => 5 [category_name] => linux优化 [category_pid] => 4 [category_addtime] => 0 [category_order] => 0 ) [1] => Array ( [category_id] => 6 [category_name] => 虚拟化 [category_pid] => 4 [category_addtime] => 1478228220 [category_order] => 0 ) [2] => Array ( [category_id] => 7 [category_name] => Mysql优化与开发 [category_pid] => 4 [category_addtime] => 1478188800 [category_order] => 0 ) [3] => Array ( [category_id] => 8 [category_name] => 高可用与虚拟化 [category_pid] => 4 [category_addtime] => 1478394120 [category_order] => 0 ) ) ) [1] => Array ( [category_id] => 15 [category_name] => Mysql [category_pid] => 3 [category_addtime] => 1480555980 [category_order] => 0 [category_child] => Array ( [0] => Array ( [category_id] => 16 [category_name] => 优化 [category_pid] => 15 [category_addtime] => 1480555980 [category_order] => 0 ) [1] => Array ( [category_id] => 17 [category_name] => Sql编程 [category_pid] => 15 [category_addtime] => 1480556040 [category_order] => 8 ) ) ) ) ) )
それでは、データベースから取り出した 2 次元配列はどのようにして上記のような配列になるのでしょうか?
例:
上記のフォームに次の 2 次元配列を実装したいとします。
[php] view plain copy
$arr=array( array('id'=>'1','name'=>'北京','pid'=>'0'), array('id'=>'2','name'=>'上海','pid'=>'0'), array('id'=>'3','name'=>'浦东','pid'=>'2'), array('id'=>'4','name'=>'朝阳','pid'=>'1'), array('id'=>'5','name'=>'广州','pid'=>'0'), array('id'=>'6','name'=>'三里屯','pid'=>'4'), array('id'=>'7','name'=>'广东','pid'=>'5'), array('id'=>'8','name'=>'三里','pid'=>'4'), array('id'=>'10','name'=>'小胡同','pid'=>'8') );
最初の方法: 主キーの ID 番号と同じになる配列のインデックスを使用して、まず配列にインデックスを追加します:
[php] プレーンコピーを表示
$arr=array( 1=>array('id'=>'1','name'=>'北京','pid'=>'0'), 2=>array('id'=>'2','name'=>'上海','pid'=>'0'), 3=>array('id'=>'3','name'=>'浦东','pid'=>'2'), 4=>array('id'=>'4','name'=>'朝阳','pid'=>'1'), 5=>array('id'=>'5','name'=>'广州','pid'=>'0'), 6=>array('id'=>'6','name'=>'三里屯','pid'=>'4'), 7=>array('id'=>'7','name'=>'广东','pid'=>'5'), 8=>array('id'=>'8','name'=>'三里','pid'=>'4'), 10=>array('id'=>'10','name'=>'小胡同','pid'=>'8') );
利用索引的下标,判断该栏目是否存在父栏目,如果存在就把该栏目放到父栏目的son子数组里面
[php] view plain copy
function generateTree($items){ $tree = array(); foreach($items as $item){ //判断是否有数组的索引== if(isset($items[$item['pid']])){ //查找数组里面是否有该分类 如 isset($items[0]) isset($items[1]) $items[$item['pid']]['son'][] = &$items[$item['id']]; //上面的内容变化,$tree里面的值就变化 }else{ $tree[] = &$items[$item['id']]; //把他的地址给了$tree } } return $tree; }
上面这个程序有一个主要问题,数组的索引是我们手动添加的?那我们可不可以自动添加数组索引呢?当然可以,下面这个程序就实现了,自动为数组添加索引然后再把子栏目放到父栏目的son数组中,思想和上面的程序是一样的
[php] view plain copy
function make_tree($list,$pk='id',$pid='pid',$child='_child',$root=0){ $tree=array(); $packData=array(); foreach ($list as $data) { <span style="white-space:pre"> </span>//转换为带有主键id的数组 $packData[$data[$pk]] = $data; //$packData[1]=$data; $packData[2]=$data } foreach ($packData as $key =>$val){ if($val[$pid]==$root){ //代表跟节点 $tree[]=& $packData[$key]; }else{ //找到其父类 $packData[$val[$pid]][$child][]=& $packData[$key]; } } return $tree; }
第二种方法:使用递归来查找子栏目
思想:使用递归来查找每个栏目中的子栏目,直到找到最后一个子栏目以后再一层层往外运行调试的话,可以打印
tree中,,为了方便理解,可以打印$tree去观察数组的变化
[php] view plain copy
array('id'=>'6','name'=>'三里屯','pid'=>'4'), [php] view plain copyfunction make_tree1($list,$pk='id',$pid='pid',$child='_child',$root=0){ $tree=array(); foreach($list as $key=> $val){ if($val[$pid]==$root){ //获取当前$pid所有子类 unset($list[$key]); if(! empty($list)){ $child=make_tree1($list,$pk,$pid,$child,$val[$pk]); //来来来 找北京的子栏目 递归 空 if(!empty($child)){ $val['_child']=$child; } } $tree[]=$val; } } return $tree; }
为了更好的理解递归,大家可以找一个小程序测试一下例如下面这个求和的程序
大家可以分析一下$n的输出从2,3 …..10,而不是从10,9—-2,我从这个程序才理解了一下上面那个程序的递归是如何实现的,总之:递归是很有意思的一个东西,希望大家好好理解
[php] view plain copy
function sum($n){ $a=0; if($n>1){ $a=sum($n-1)+$n; /*if($n>5){ echo "$n <br />" ; }*/ echo "$n<br />"; }else{ $a=1; } return $a; } echo sum(10);
根据父id获得所有下级子类id的数据
#$id = 父级id, $array = 所有分类public function getSon($id,$array){ static $list; foreach ($array as $k => $v) { if($v['parent_id'] == $id){ $list[] = $array[$k]; self::getSon($v['id'],$array); } } return $list; }
相关推荐:
以上がPHP Infinitus 分類の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。