Laravel无限级分类与传统递归无限级分类的实现

作者: 温新

分类: 【Laravel】

阅读: 3236

时间: 2021-01-10 13:25:11

Laravel结合模型实现无限级分类

假设有Category模型文件,位于app\Models\Category.php,有了模型文件,下面开始结合模型实现无限极分类。

第一步:模型文件中编写代码

<span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// app/Models/Category.php</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">/**</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">* 使用关联模型获取顶级分类</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">*/</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">public</span> <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">function</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">cates</span>() {</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">return</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$this</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">hasMany</span>(<span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">get_class</span>(<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$this</span>), <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'pid'</span> ,<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'id'</span>);</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">}</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">/**</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">* 获取所有子集分类</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">*/</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">public</span> <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">function</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">childCates</span>() {</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">return</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$this</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">cates</span>()<span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">with</span>( <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'childCates'</span> );</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">}</span>

第二步:控制器中调用

<span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// CategroyController.php</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">public</span> <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">function</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">index</span>()</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$cates</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">Menu</span>::<span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">with</span>(<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'childCates'</span>)<span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">where</span>(<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'pid'</span>,<span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">0</span>)<span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">get</span>();</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">dd</span>(<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$cates</span>);</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">}</span>

没错,就这样完成了。

特别注意:模型cates方法中使用了get_class($this)方法,在此例中获取当前模型文件,即App\Models\Category",因此,该方法也可以改为如下方法更容易理解。

<span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">public</span> <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">function</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">cates</span>() {</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">return</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$this</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">hasMany</span>(<span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">Category</span>::<span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">class</span>, <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'pid'</span> ,<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'id'</span>);</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">}</span>

为什么要使用hasMany方法?

hasMany是模型中一对多的关系,在分类中可以理解了,一个分类可以对应多个子分类,这就形成了一对多的关系。如一个顶级分类可能对应多个子分类。

Laravel中使用递归实现无限级分类

作为演示,我这里还是放在Category.php模型文件中

<span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">/**</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">* 递归生成无限极分类树</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">*</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">* @param array $data   待分类的数组</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">* @param int $pid      父级ID</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">* @param int $level    缩进</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">*/</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">public</span> <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">function</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">makeCategoryTree</span>( <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$data</span>, <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$pid</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">0</span>, <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$level</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">0</span>)</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">static</span>  <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$arr</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span> [];</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">foreach</span> (<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$data</span> <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">as</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$k</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=></span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$v</span>) {</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">if</span> (<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$v</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">pid</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">==</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$pid</span>) {</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">            <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">if</span>(<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$v</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">pid</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">!=</span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">0</span>){</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">                <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$v</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">name</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span> <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'|'</span> . <span style="box-sizing: border-box;color: rgb(232, 191, 106) !important">str_repeat</span>(<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'--'</span>, <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$level</span>) . <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$v</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">name</span>;</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">            }</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">            <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$v</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">level</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$level</span>;</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">            <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$arr</span>[] <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$v</span>;</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">            <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$this</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">makeCategoryTree</span>(<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$data</span>,<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$v</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">id</span>,<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$level</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">+</span><span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">2</span>);</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">        }</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    }</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">return</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$arr</span>;</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">}</span>

对于这两种方法而言,Laravel中的实现更为轻松容易,但是隐藏了更多的细节,当时间久了再来看时,或许一时间不容易认出这就是无限极分类吗?

对于使用而言,结合实际情况来使用。

我是小白,期待和优秀的你一起同行!

小白

2021年01月10日

请登录后再评论