Maison > Article > développement back-end > PHP实现无限极归类
PHP实现无限极分类
利用两个for循环实现无限级分类
表:
字段名 | 字段类型 | 备注 | 默认值 |
---|---|---|---|
id | int | 主键 auto-increment | |
name | varchar | 分类名称 | |
pid | int | 父类id | 0 |
顶级分类的 pid 默认就是0了。当我们想取出某个分类的子分类树的时候,基本思路就是递归,当然,出于效率问题不建议每次递归都查询数据库,通常的做法是先将所有分类取出来,数据保存到PHP数组里,再进行处理,最后还可以将结果缓存起来以提高下次请求的效率。
先来构建一个原始数组,这个直接从数据库中查询出来就行:
<code class=" hljs php"><span class="hljs-variable">$categories</span> = <span class="hljs-keyword">array</span>( <span class="hljs-keyword">array</span>(<span class="hljs-string">'id'</span>=><span class="hljs-number">1</span>,<span class="hljs-string">'name'</span>=><span class="hljs-string">'电脑'</span>,<span class="hljs-string">'pid'</span>=><span class="hljs-number">0</span>), <span class="hljs-keyword">array</span>(<span class="hljs-string">'id'</span>=><span class="hljs-number">2</span>,<span class="hljs-string">'name'</span>=><span class="hljs-string">'手机'</span>,<span class="hljs-string">'pid'</span>=><span class="hljs-number">0</span>), <span class="hljs-keyword">array</span>(<span class="hljs-string">'id'</span>=><span class="hljs-number">3</span>,<span class="hljs-string">'name'</span>=><span class="hljs-string">'笔记本'</span>,<span class="hljs-string">'pid'</span>=><span class="hljs-number">1</span>), <span class="hljs-keyword">array</span>(<span class="hljs-string">'id'</span>=><span class="hljs-number">4</span>,<span class="hljs-string">'name'</span>=><span class="hljs-string">'台式机'</span>,<span class="hljs-string">'pid'</span>=><span class="hljs-number">1</span>), <span class="hljs-keyword">array</span>(<span class="hljs-string">'id'</span>=><span class="hljs-number">5</span>,<span class="hljs-string">'name'</span>=><span class="hljs-string">'智能机'</span>,<span class="hljs-string">'pid'</span>=><span class="hljs-number">2</span>), <span class="hljs-keyword">array</span>(<span class="hljs-string">'id'</span>=><span class="hljs-number">6</span>,<span class="hljs-string">'name'</span>=><span class="hljs-string">'功能机'</span>,<span class="hljs-string">'pid'</span>=><span class="hljs-number">2</span>), <span class="hljs-keyword">array</span>(<span class="hljs-string">'id'</span>=><span class="hljs-number">7</span>,<span class="hljs-string">'name'</span>=><span class="hljs-string">'超级本'</span>,<span class="hljs-string">'pid'</span>=><span class="hljs-number">3</span>), <span class="hljs-keyword">array</span>(<span class="hljs-string">'id'</span>=><span class="hljs-number">8</span>,<span class="hljs-string">'name'</span>=><span class="hljs-string">'游戏本'</span>,<span class="hljs-string">'pid'</span>=><span class="hljs-number">3</span>),);</code>
目标是将它转化为下面这种结构
电脑 >笔记本 >>超级本 >> 游戏本 > 台式机
手机 > 智能机 > 功能机
用数组来表示的话,可以增加一个 children 键来存储它的子分类:
<code class=" hljs php"><span class="hljs-keyword">array</span>( <span class="hljs-comment">//1对应$categories中的id ,方便直接读取</span> <span class="hljs-number">1</span> => <span class="hljs-keyword">array</span>( <span class="hljs-string">'id'</span>=><span class="hljs-number">1</span>, <span class="hljs-string">'name'</span>=><span class="hljs-string">'电脑'</span>, <span class="hljs-string">'pid'</span>=><span class="hljs-number">0</span>, children=><span class="hljs-keyword">array</span>( &<span class="hljs-keyword">array</span>( <span class="hljs-string">'id'</span>=><span class="hljs-number">3</span>, <span class="hljs-string">'name'</span>=><span class="hljs-string">'笔记本'</span>, <span class="hljs-string">'pid'</span>=><span class="hljs-number">1</span>, <span class="hljs-string">'children'</span>=><span class="hljs-keyword">array</span>( <span class="hljs-comment">//此处省略</span> ) ), &<span class="hljs-keyword">array</span>( <span class="hljs-string">'id'</span>=><span class="hljs-number">4</span>, <span class="hljs-string">'name'</span>=><span class="hljs-string">'台式机'</span>, <span class="hljs-string">'pid'</span>=><span class="hljs-number">1</span>, <span class="hljs-string">'children'</span>=><span class="hljs-keyword">array</span>( <span class="hljs-comment">//此处省略</span> ) ), ) ), <span class="hljs-comment">//其他分类省略</span>)</code>
<code class=" hljs php"><span class="hljs-variable">$tree</span> = <span class="hljs-keyword">array</span>();<span class="hljs-comment">//第一步,将所有的分类id作为数组key,并创建children单元</span><span class="hljs-keyword">foreach</span>(<span class="hljs-variable">$categories</span> <span class="hljs-keyword">as</span> <span class="hljs-variable">$category</span>){ <span class="hljs-variable">$tree</span>[<span class="hljs-variable">$category</span>[<span class="hljs-string">'id'</span>]] = <span class="hljs-variable">$category</span>; <span class="hljs-variable">$tree</span>[<span class="hljs-variable">$category</span>[<span class="hljs-string">'id'</span>]][<span class="hljs-string">'children'</span>] = <span class="hljs-keyword">array</span>();}<span class="hljs-comment">//第二步,利用引用,将每个分类添加到父类children数组中,这样一次遍历即可形成树形结构。</span><span class="hljs-keyword">foreach</span> (<span class="hljs-variable">$tree</span> <span class="hljs-keyword">as</span> <span class="hljs-variable">$key</span>=><span class="hljs-variable">$value</span>) { <span class="hljs-keyword">if</span> (<span class="hljs-variable">$value</span>[<span class="hljs-string">'pid'</span>] != <span class="hljs-number">0</span>) { <span class="hljs-variable">$tree</span>[<span class="hljs-variable">$value</span>[<span class="hljs-string">'pid'</span>]][<span class="hljs-string">'children'</span>][] = &<span class="hljs-variable">$tree</span>[<span class="hljs-variable">$key</span>]; }}print_r(<span class="hljs-variable">$tree</span>);</code>
<code>注:必须通过引用, 否则不会一次遍历就生成最终的结果.</code>
<code class=" hljs php"><span class="hljs-keyword">Array</span>( [<span class="hljs-number">1</span>] => <span class="hljs-keyword">Array</span> ( [id] => <span class="hljs-number">1</span> [name] => 电脑 [pid] => <span class="hljs-number">0</span> [children] => <span class="hljs-keyword">Array</span> ( [<span class="hljs-number">0</span>] => <span class="hljs-keyword">Array</span> ( [id] => <span class="hljs-number">3</span> [name] => 笔记本 [pid] => <span class="hljs-number">1</span> [children] => <span class="hljs-keyword">Array</span> ( [<span class="hljs-number">0</span>] => <span class="hljs-keyword">Array</span> ( [id] => <span class="hljs-number">7</span> [name] => 超级本 [pid] => <span class="hljs-number">3</span> [children] => <span class="hljs-keyword">Array</span> ( ) ) [<span class="hljs-number">1</span>] => <span class="hljs-keyword">Array</span> ( [id] => <span class="hljs-number">8</span> [name] => 游戏本 [pid] => <span class="hljs-number">3</span> [children] => <span class="hljs-keyword">Array</span> ( ) ) ) ) [<span class="hljs-number">1</span>] => <span class="hljs-keyword">Array</span> ( [id] => <span class="hljs-number">4</span> [name] => 台式机 [pid] => <span class="hljs-number">1</span> [children] => <span class="hljs-keyword">Array</span> ( ) ) ) ) [<span class="hljs-number">2</span>] => <span class="hljs-keyword">Array</span> ( [id] => <span class="hljs-number">2</span> [name] => 手机 [pid] => <span class="hljs-number">0</span> [children] => <span class="hljs-keyword">Array</span> ( [<span class="hljs-number">0</span>] => <span class="hljs-keyword">Array</span> ( [id] => <span class="hljs-number">5</span> [name] => 智能机 [pid] => <span class="hljs-number">2</span> [children] => <span class="hljs-keyword">Array</span> ( ) ) [<span class="hljs-number">1</span>] => <span class="hljs-keyword">Array</span> ( [id] => <span class="hljs-number">6</span> [name] => 功能机 [pid] => <span class="hljs-number">2</span> [children] => <span class="hljs-keyword">Array</span> ( ) ) ) ) [<span class="hljs-number">3</span>] => <span class="hljs-keyword">Array</span> ( [id] => <span class="hljs-number">3</span> [name] => 笔记本 [pid] => <span class="hljs-number">1</span> [children] => <span class="hljs-keyword">Array</span> ( [<span class="hljs-number">0</span>] => <span class="hljs-keyword">Array</span> ( [id] => <span class="hljs-number">7</span> [name] => 超级本 [pid] => <span class="hljs-number">3</span> [children] => <span class="hljs-keyword">Array</span> ( ) ) [<span class="hljs-number">1</span>] => <span class="hljs-keyword">Array</span> ( [id] => <span class="hljs-number">8</span> [name] => 游戏本 [pid] => <span class="hljs-number">3</span> [children] => <span class="hljs-keyword">Array</span> ( ) ) ) ) [<span class="hljs-number">4</span>] => <span class="hljs-keyword">Array</span> ( [id] => <span class="hljs-number">4</span> [name] => 台式机 [pid] => <span class="hljs-number">1</span> [children] => <span class="hljs-keyword">Array</span> ( ) ) [<span class="hljs-number">5</span>] => <span class="hljs-keyword">Array</span> ( [id] => <span class="hljs-number">5</span> [name] => 智能机 [pid] => <span class="hljs-number">2</span> [children] => <span class="hljs-keyword">Array</span> ( ) ) [<span class="hljs-number">6</span>] => <span class="hljs-keyword">Array</span> ( [id] => <span class="hljs-number">6</span> [name] => 功能机 [pid] => <span class="hljs-number">2</span> [children] => <span class="hljs-keyword">Array</span> ( ) ) [<span class="hljs-number">7</span>] => <span class="hljs-keyword">Array</span> ( [id] => <span class="hljs-number">7</span> [name] => 超级本 [pid] => <span class="hljs-number">3</span> [children] => <span class="hljs-keyword">Array</span> ( ) ) [<span class="hljs-number">8</span>] => <span class="hljs-keyword">Array</span> ( [id] => <span class="hljs-number">8</span> [name] => 游戏本 [pid] => <span class="hljs-number">3</span> [children] => <span class="hljs-keyword">Array</span> ( ) ))</code>
优点:关系清楚,修改上下级关系简单。
缺点:使用PHP处理,如果分类数量庞大,效率也会降低。
原文 http://blog.csdn.net/u013927110/article/details/44086253