ホームページ  >  記事  >  バックエンド開発  >  PHPを使用して無制限の分類クエリを実装する

PHPを使用して無制限の分類クエリを実装する

不言
不言オリジナル
2018-06-08 17:28:321607ブラウズ

この記事は、再帰を使用する場合と再帰を使用しない場合の PHP での無限分類の実装を 2 つの状況に分けて紹介しています。興味のある方は、

#PHP を長くやっている方は参照してください。バックエンド管理システムの不可欠なアプリケーション モジュールは列の分類であることがわかりました。一般に、列は無限のレベルに作成する必要があります。これは、理論的には各列にサブ列を追加できることを意味します。私の意見では、この状況の処理は全体としてはそれほど複雑ではありません。比較的難しい点は無限列のクエリだけです。

この状況について簡単に説明します。この種の無限列をクエリするには、一般に 2 つの方法があります。1 つはスタック メカニズムを使用する方法で、もう 1 つは再帰関数を使用する方法です。再帰関数の実装メカニズムもスタックの助けを借りて実装されます)。以下では、これら 2 つの方法を個別に紹介します。

再帰関数の実装方法

上で述べたように、再帰関数もスタック機構を利用して実装されますが、その基礎となるスタック処理はプログラマにとっては困難です。透過的であり、プログラマはアプリケーションの実装ロジックのみを気にする必要があります。したがって、上記の問題に対処するには再帰を使用する方が理解しやすく、コードも比較的簡潔になります。

再帰関数を使用しているため、名前からカスタム関数を使用する必要があることがわかります。まず実装のアイデアについて簡単に説明し、具体的な詳細をコードに反映させていきます。

各レイヤーの関数の主な仕事は、親 ID が現在の ID である列を検索することです。それを見つけた後、独自の関数を再度呼び出し、見つかった列の ID を次のレイヤーの親 ID として使用します。

フローチャートは次のとおりです

図 1

上記の説明を理解できるかわかりません。問題はありません。コードを直接見てみましょう。


<?php
/**
 * 个人博客:迹忆博客
 * 博客地址:www.onmpw.com
 * 递归实现无限极分类
 */
$channels = array(
  array(&#39;id&#39;=>1,&#39;name&#39;=>"衣服",&#39;parId&#39;=>0),
  array(&#39;id&#39;=>2,&#39;name&#39;=>"书籍",&#39;parId&#39;=>0),
  array(&#39;id&#39;=>3,&#39;name&#39;=>"T恤",&#39;parId&#39;=>1),
  array(&#39;id&#39;=>4,&#39;name&#39;=>"裤子",&#39;parId&#39;=>1),
  array(&#39;id&#39;=>5,&#39;name&#39;=>"鞋子",&#39;parId&#39;=>1),
  array(&#39;id&#39;=>6,&#39;name&#39;=>"皮鞋",&#39;parId&#39;=>5),
  array(&#39;id&#39;=>7,&#39;name&#39;=>"运动鞋",&#39;parId&#39;=>5),
  array(&#39;id&#39;=>8,&#39;name&#39;=>"耐克",&#39;parId&#39;=>7),
  array(&#39;id&#39;=>9,&#39;name&#39;=>"耐克",&#39;parId&#39;=>3),
  array(&#39;id&#39;=>10,&#39;name&#39;=>"鸿星尔克",&#39;parId&#39;=>7),
  array(&#39;id&#39;=>11,&#39;name&#39;=>"小说",&#39;parId&#39;=>2),
  array(&#39;id&#39;=>12,&#39;name&#39;=>"科幻小说",&#39;parId&#39;=>11),
  array(&#39;id&#39;=>13,&#39;name&#39;=>"古典名著",&#39;parId&#39;=>11),
  array(&#39;id&#39;=>14,&#39;name&#39;=>"文学",&#39;parId&#39;=>2),
  array(&#39;id&#39;=>15,&#39;name&#39;=>"四书五经",&#39;parId&#39;=>14)
);
$html = array();
/**
 * 递归查找父id为$parid的结点
 * @param array $html  按照父-》子的结构存放查找出来的结点
 * @param int $parid  指定的父id
 * @param array $channels  数据数组
 * @param int $dep  遍历的深度,初始化为1
 */
function getChild(&$html,$parid,$channels,$dep){
  /*
   * 遍历数据,查找parId为参数$parid指定的id
   */
  for($i = 0;$i<count($channels);$i++){
    if($channels[$i][&#39;parId&#39;] == $parid){
      $html[] = array(&#39;id&#39;=>$channels[$i][&#39;id&#39;],&#39;name&#39;=>$channels[$i][&#39;name&#39;],&#39;dep&#39;=>$dep);
      getChild($html,$channels[$i][&#39;id&#39;],$channels,$dep+1);
    }
  }
}
getChild($html,0,$channels,1);
?>

これは、無限列クエリを再帰的に実装するためのコア コードです。図 1 に基づいて実装プロセスを理解します。

非再帰的、つまり、スタック メカニズムを使用して無限列のクエリを実現します

上記では、無限列のクエリを実行するための再帰の使用について簡単に紹介しました。以下では、非再帰的メソッドを簡単に紹介しましょう。再帰関数は使用していませんが、無限カラムの構造ページを考慮すると、この問題を解決するには再帰実装メカニズム、つまりスタックメカニズムを参照する必要があります。

私が学校にいたとき、先生は、実際、スタックの中心的なメカニズムは、先入れ、後出しという 4 つの単語だけであると言いました。

ここではスタックの仕組みについてはあまり説明しませんが、主にスタックを使用して無制限の列クエリを実装する方法について説明します。

1. まず先頭の列をスタックにプッシュします。

2. 先頭の要素をスタックからポップします。

3. ポップされた要素を配列に格納し、その深さをマークします。 (深さは親列の深さに 1 を加えます)

4. ポップされた要素を親列として取得し、そのサブ列を検索します

5 見つかったサブ列を入力します。 -列をスタックに挿入し、ステップ 2

6 を繰り返します。スタックが空であると判断された場合、プロセスは終了します。

上記のステップを変換することで、これらのステップを PHP コードに変換できます。コア コードは次のとおりです


<?php
/**
 * 个人博客:迹忆博客
 * 博客地址:www.onmpw.com
*使用非递归,即使用栈的方式实现栏目的无限极分类查询
*/
$channels = array(
  array(&#39;id&#39;=>1,&#39;name&#39;=>"衣服",&#39;parId&#39;=>0),
  array(&#39;id&#39;=>2,&#39;name&#39;=>"书籍",&#39;parId&#39;=>0),
  array(&#39;id&#39;=>3,&#39;name&#39;=>"T恤",&#39;parId&#39;=>1),
  array(&#39;id&#39;=>4,&#39;name&#39;=>"裤子",&#39;parId&#39;=>1),
  array(&#39;id&#39;=>5,&#39;name&#39;=>"鞋子",&#39;parId&#39;=>1),
  array(&#39;id&#39;=>6,&#39;name&#39;=>"皮鞋",&#39;parId&#39;=>5),
  array(&#39;id&#39;=>7,&#39;name&#39;=>"运动鞋",&#39;parId&#39;=>5),
  array(&#39;id&#39;=>8,&#39;name&#39;=>"耐克",&#39;parId&#39;=>7),
  array(&#39;id&#39;=>9,&#39;name&#39;=>"耐克",&#39;parId&#39;=>3),
  array(&#39;id&#39;=>10,&#39;name&#39;=>"鸿星尔克",&#39;parId&#39;=>7),
  array(&#39;id&#39;=>11,&#39;name&#39;=>"小说",&#39;parId&#39;=>2),
  array(&#39;id&#39;=>12,&#39;name&#39;=>"科幻小说",&#39;parId&#39;=>11),
  array(&#39;id&#39;=>13,&#39;name&#39;=>"古典名著",&#39;parId&#39;=>11),
  array(&#39;id&#39;=>14,&#39;name&#39;=>"文学",&#39;parId&#39;=>2),
  array(&#39;id&#39;=>15,&#39;name&#39;=>"四书五经",&#39;parId&#39;=>14)
);
$stack = array(); //定义一个空栈
$html = array();  //用来保存各个栏目之间的关系以及该栏目的深度
/*
 * 自定义入栈函数
 */
function pushStack(&$stack,$channel,$dep){
  array_push($stack, array(&#39;channel&#39;=>$channel,&#39;dep&#39;=>$dep));
}
/*
 * 自定义出栈函数
 */
function popStack(&$stack){
  return array_pop($stack);
}
/*
 * 首先将顶级栏目压入栈中
 */
foreach($channels as $key=>$val){
  if($val[&#39;parId&#39;] == 0)
    pushStack($stack,$val,0);
}
/*
 * 将栈中的元素出栈,查找其子栏目
 */
do{
  $par = popStack($stack); //将栈顶元素出栈
  /*
   * 查找以此栏目为父级栏目的id,将这些栏目入栈
   */
  for($i=0;$i<count($channels);$i++){
    if($channels[$i][&#39;parId&#39;] == $par[&#39;channel&#39;][&#39;id&#39;]){
      pushStack($stack,$channels[$i],$par[&#39;dep&#39;]+1);
    }
  }
  /*
   * 将出栈的栏目以及该栏目的深度保存到数组中
   */
  $html[] = array(&#39;id&#39;=>$par[&#39;channel&#39;][&#39;id&#39;],&#39;name&#39;=>$par[&#39;channel&#39;][&#39;name&#39;],&#39;dep&#39;=>$par[&#39;dep&#39;]);
}while(count($stack)>0);

上記は、非再帰メソッドを使用して実装されています。

上記がこの記事の全内容です。その他の関連コンテンツについては、PHP 中国語 Web サイトをご覧ください。

関連する推奨事項:

php を使用して無限ツリー メニューを作成する

#

以上がPHPを使用して無制限の分類クエリを実装するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。