Maison >développement back-end >tutoriel php >php利用递归函数实现无限级归类
php利用递归函数实现无限级分类
相信很多学php的很多小伙伴都会尝试做一个网上商城作为提升自己技术的一种途径。各种对商品分类,商品名之类的操作应该是得心应手,那么就可以尝试下无限级分类列表的制作了。
什么是无限级分类?
无限级分类是一种分类技巧,例如部门组织,文章分类,学科分类等常用到无限级分类,将其简单理解成分类就好了。其实我们仔细想一下,生活中的分类简直太多了,衣服可以分为男装和女装,也可以分为上衣和裤子,也可以根据年龄段分类。分类无处不在,分类显得“无限”。我这里就不说无限分类的必要性了。
无限级分类原理简介
无限分类看似"高大上",实际上原理是非常简单的 。无限分类不仅仅需要代码的巧妙性,也要依托数据库设计的合理性。要满足无限级分类,数据库需要有两个必须的字段,id,pid。id用来标识自身,而pid则是用来表明父级id。也就是说,每个分类记录不仅描述了自身,还描述了与其关心最为紧密的另一个id。看似复杂的事情被这样一个小技巧解决了。
闲话不多说,该展现本文的实例了。
作为一个狂热海贼迷,这篇的实例我就以《海贼王》人物组织做案例。
数据库准备:
建表onepiece:
<span style="color: #0000ff;">create</span> <span style="color: #0000ff;">table</span><span style="color: #000000;"> onepiece( id </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> auto_increment, pid </span><span style="color: #0000ff;">int</span> <span style="color: #808080;">not</span> <span style="color: #0000ff;">null</span><span style="color: #000000;">, name </span><span style="color: #0000ff;">varchar</span>(<span style="color: #800000; font-weight: bold;">225</span>) <span style="color: #808080;">not</span> <span style="color: #0000ff;">null</span><span style="color: #000000;">, </span><span style="color: #0000ff;">primary</span> <span style="color: #0000ff;">key</span><span style="color: #000000;">(id));</span>
插入测试数据:
<span style="color: #0000ff;">insert</span> onepiece <span style="color: #0000ff;">values</span><span style="color: #000000;"> (</span><span style="color: #800000; font-weight: bold;">1</span>,<span style="color: #800000; font-weight: bold;">0</span>,<span style="color: #ff0000;">'</span><span style="color: #ff0000;">海军</span><span style="color: #ff0000;">'</span><span style="color: #000000;">), (</span><span style="color: #800000; font-weight: bold;">2</span>,<span style="color: #800000; font-weight: bold;">0</span>,<span style="color: #ff0000;">'</span><span style="color: #ff0000;">海贼</span><span style="color: #ff0000;">'</span><span style="color: #000000;">), (</span><span style="color: #800000; font-weight: bold;">3</span>,<span style="color: #800000; font-weight: bold;">0</span>,<span style="color: #ff0000;">'</span><span style="color: #ff0000;">革命军</span><span style="color: #ff0000;">'</span><span style="color: #000000;">), (</span><span style="color: #800000; font-weight: bold;">4</span>,<span style="color: #800000; font-weight: bold;">1</span>,<span style="color: #ff0000;">'</span><span style="color: #ff0000;">青雉</span><span style="color: #ff0000;">'</span><span style="color: #000000;">), (</span><span style="color: #800000; font-weight: bold;">5</span>,<span style="color: #800000; font-weight: bold;">1</span>,<span style="color: #ff0000;">'</span><span style="color: #ff0000;">赤犬</span><span style="color: #ff0000;">'</span><span style="color: #000000;">), (</span><span style="color: #800000; font-weight: bold;">6</span>,<span style="color: #800000; font-weight: bold;">1</span>,<span style="color: #ff0000;">'</span><span style="color: #ff0000;">黄猿</span><span style="color: #ff0000;">'</span><span style="color: #000000;">), (</span><span style="color: #800000; font-weight: bold;">7</span>,<span style="color: #800000; font-weight: bold;">2</span>,<span style="color: #ff0000;">'</span><span style="color: #ff0000;">四皇</span><span style="color: #ff0000;">'</span><span style="color: #000000;">), (</span><span style="color: #800000; font-weight: bold;">8</span>,<span style="color: #800000; font-weight: bold;">2</span>,<span style="color: #ff0000;">'</span><span style="color: #ff0000;">七武海</span><span style="color: #ff0000;">'</span><span style="color: #000000;">), (</span><span style="color: #800000; font-weight: bold;">9</span>,<span style="color: #800000; font-weight: bold;">2</span>,<span style="color: #ff0000;">'</span><span style="color: #ff0000;">草帽海贼团</span><span style="color: #ff0000;">'</span><span style="color: #000000;">), (</span><span style="color: #800000; font-weight: bold;">10</span>,<span style="color: #800000; font-weight: bold;">9</span>,<span style="color: #ff0000;">'</span><span style="color: #ff0000;">索隆</span><span style="color: #ff0000;">'</span><span style="color: #000000;">), (</span><span style="color: #800000; font-weight: bold;">11</span>,<span style="color: #800000; font-weight: bold;">7</span>,<span style="color: #ff0000;">'</span><span style="color: #ff0000;">香克斯</span><span style="color: #ff0000;">'</span><span style="color: #000000;">), (</span><span style="color: #800000; font-weight: bold;">12</span>,<span style="color: #800000; font-weight: bold;">8</span>,<span style="color: #ff0000;">'</span><span style="color: #ff0000;">多弗朗明哥</span><span style="color: #ff0000;">'</span><span style="color: #000000;">), (</span><span style="color: #800000; font-weight: bold;">13</span>,<span style="color: #800000; font-weight: bold;">8</span>,<span style="color: #ff0000;">'</span><span style="color: #ff0000;">克洛克达尔</span><span style="color: #ff0000;">'</span>);
这里还是科普下海贼王里面的设定:世界分为三大阵营:海军,海贼,革命军。海军有大将:青雉,赤犬,黄猿。海贼有:四皇,七武海,草帽海贼团。四皇有香克斯,七武海有多弗朗明哥,克洛克达尔,草帽海贼团有索隆。(打个广告:海贼王真的很好看)。
最终目的:
我们今天制作的是两种形式的无限级分类形式,一种是下拉列表式,一种则是导航Link式的。直接上效果图了:
下拉列表式导航Link式
实例代码:
我封装了一个Unlimited类,用来调用diaplayList()展现下拉列表形式,调用diaplayLink展现导航Link分类。也可以增加(addNodes())和删除(deleteNodes)分类。
<span style="color: #000000;">php</span><span style="color: #0000ff;">class</span><span style="color: #000000;"> Unlimited{ </span><span style="color: #0000ff;">protected</span> <span style="color: #800080;">$mysqli</span><span style="color: #000000;">; </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> __construct(<span style="color: #800080;">$config</span><span style="color: #000000;">){ </span><span style="color: #800080;">$this</span>->mysqli=<span style="color: #0000ff;">new</span> mysqli(<span style="color: #800080;">$config</span>['host'],<span style="color: #800080;">$config</span>['user'],<span style="color: #800080;">$config</span>['pwd'<span style="color: #000000;">]); </span><span style="color: #800080;">$this</span>->mysqli->select_db(<span style="color: #800080;">$config</span>['db'<span style="color: #000000;">]); </span><span style="color: #800080;">$this</span>->mysqli->set_charset('utf8'<span style="color: #000000;">); </span><span style="color: #0000ff;">if</span> (<span style="color: #800080;">$this</span>->mysqli-><span style="color: #000000;">connect_errno) { </span><span style="color: #0000ff;">echo</span> <span style="color: #800080;">$this</span>->mysqli-><span style="color: #000000;">connect_error; } } </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> getList(<span style="color: #800080;">$pid</span>=0,&<span style="color: #800080;">$result</span>=<span style="color: #0000ff;">array</span>(),<span style="color: #800080;">$spac</span>=0<span style="color: #000000;">){ </span><span style="color: #800080;">$spac</span>=<span style="color: #800080;">$spac</span>+2<span style="color: #000000;">; </span><span style="color: #800080;">$sql</span>="select * from onepiece where pid={<span style="color: #800080;">$pid</span>}"<span style="color: #000000;">; </span><span style="color: #800080;">$rs</span>=<span style="color: #800080;">$this</span>->mysqli->query(<span style="color: #800080;">$sql</span><span style="color: #000000;">); </span><span style="color: #0000ff;">while</span>(<span style="color: #800080;">$row</span>=<span style="color: #800080;">$rs</span>-><span style="color: #000000;">fetch_assoc()) { </span><span style="color: #800080;">$row</span>['name']=<span style="color: #008080;">str_repeat</span>('  ',<span style="color: #800080;">$spac</span>).<span style="color: #800080;">$row</span>['name'<span style="color: #000000;">]; </span><span style="color: #800080;">$result</span>[]=<span style="color: #800080;">$row</span><span style="color: #000000;">; </span><span style="color: #800080;">$this</span>->getList(<span style="color: #800080;">$row</span>['id'],<span style="color: #800080;">$result</span>,<span style="color: #800080;">$spac</span><span style="color: #000000;">); } </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$result</span><span style="color: #000000;">; } </span><span style="color: #008000;">/*</span><span style="color: #008000;">* * 展现下拉列表式分类 * @return [type] </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> displayList(){ </span><span style="color: #800080;">$rs</span>=<span style="color: #800080;">$this</span>-><span style="color: #000000;">getList(); </span><span style="color: #800080;">$str</span>="<select name="cate">"<span style="color: #000000;">; </span><span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$rs</span> <span style="color: #0000ff;">as</span> <span style="color: #800080;">$key</span> => <span style="color: #800080;">$val</span><span style="color: #000000;">) { </span><span style="color: #800080;">$str</span>.="<option>{<span style="color: #800080;">$val</span>['name']}</option>"<span style="color: #000000;">; } </span><span style="color: #800080;">$str</span>.="</select>"<span style="color: #000000;">; </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$str</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> getLink(<span style="color: #800080;">$cid</span>,&<span style="color: #800080;">$result</span>=<span style="color: #0000ff;">array</span><span style="color: #000000;">()){ </span><span style="color: #800080;">$sql</span>="select * from onepiece where id={<span style="color: #800080;">$cid</span>}"<span style="color: #000000;">; </span><span style="color: #800080;">$rs</span>=<span style="color: #800080;">$this</span>->mysqli->query(<span style="color: #800080;">$sql</span><span style="color: #000000;">); </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$row</span>=<span style="color: #800080;">$rs</span>-><span style="color: #000000;">fetch_assoc()){ </span><span style="color: #800080;">$result</span>[]=<span style="color: #800080;">$row</span><span style="color: #000000;">; </span><span style="color: #800080;">$this</span>->getLink(<span style="color: #800080;">$row</span>['pid'],<span style="color: #800080;">$result</span><span style="color: #000000;">); } </span><span style="color: #0000ff;">return</span> <span style="color: #008080;">array_reverse</span>(<span style="color: #800080;">$result</span><span style="color: #000000;">); } </span><span style="color: #008000;">/*</span><span style="color: #008000;">* * 展现导航Link * @param [type] $cid [description] * @return [type] [description] </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> displayLink(<span style="color: #800080;">$cid</span><span style="color: #000000;">){ </span><span style="color: #800080;">$rs</span>=<span style="color: #800080;">$this</span>->getLink(<span style="color: #800080;">$cid</span><span style="color: #000000;">); </span><span style="color: #800080;">$str</span>=''<span style="color: #000000;">; </span><span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$rs</span> <span style="color: #0000ff;">as</span> <span style="color: #800080;">$val</span><span style="color: #000000;">) { </span><span style="color: #800080;">$str</span>.="<a href="">{<span style="color: #800080;">$val</span>['name']}</a>>"<span style="color: #000000;">; } </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$str</span><span style="color: #000000;">; } </span><span style="color: #008000;">/*</span><span style="color: #008000;">* * 增加分类 * @param [type] $pid 父类id * @param [type] $name 本类名 </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> addNodes(<span style="color: #800080;">$pid</span>,<span style="color: #800080;">$name</span><span style="color: #000000;">){ </span><span style="color: #800080;">$sql</span>="insert into onepiece values('',{<span style="color: #800080;">$pid</span>},'".<span style="color: #800080;">$name</span>."')"<span style="color: #000000;">; </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$this</span>->mysqli->query(<span style="color: #800080;">$sql</span><span style="color: #000000;">)){ </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">; } } </span><span style="color: #008000;">/*</span><span style="color: #008000;">* * 删除分类 * @param [type] $id 本类id * @return [type] </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> deleteNodes(<span style="color: #800080;">$id</span><span style="color: #000000;">){ </span><span style="color: #800080;">$sql</span>="select * from onepiece where pid ={<span style="color: #800080;">$id</span>}"<span style="color: #000000;">; </span><span style="color: #800080;">$rs</span>=<span style="color: #800080;">$this</span>->mysqli->query(<span style="color: #800080;">$sql</span><span style="color: #000000;">); </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$row</span>=<span style="color: #800080;">$rs</span>-><span style="color: #000000;">fetch_assoc()){ </span><span style="color: #800080;">$mes</span>="还有子元素,请勿删除"<span style="color: #000000;">; }</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{ </span><span style="color: #800080;">$sql</span>="delete from onepiece where id={<span style="color: #800080;">$id</span>}"<span style="color: #000000;">; </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$this</span>->mysqli->query(<span style="color: #800080;">$sql</span><span style="color: #000000;">)){ </span><span style="color: #800080;">$mes</span>="删除成功"<span style="color: #000000;">; } } </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$mes</span><span style="color: #000000;">; }}</span>
类中函数主要采取了递归函数的方法,如果理解深刻理解递归函数,其余的部分也就水到渠成了。我会在后面的部分详细介绍实现递归函数的三种方法。