An in depth analysis of PHP Infinite Classification of Tree Class

  • 2020-06-03 06:08:25
  • OfStack

PHP infinite classification, Google1 can find a lot of relevant information, the idea is more popular, but also more used is that the classification table at least id,pid,name3 fields, id self-increasing table classification, pid as the parent classification, name as the classification name, which constitutes a tree, as follows, is my query classification table results set.


<?php
// simulation PHP Infinite classification of query results 
return array(
    array(
        'id'=>1,
        'pid'=>0,
        'name'=>' The home page '
    ),
    array(
        'id'=>2,
        'pid'=>0,
        'name'=>' news '
    ),
    array(
        'id'=>3,
        'pid'=>0,
        'name'=>' The media '
    ),
    array(
        'id'=>4,
        'pid'=>0,
        'name'=>' download '
    ),
    array(
        'id'=>5,
        'pid'=>0,
        'name'=>' About us '
    ),
    array(
        'id'=>6,
        'pid'=>2,
        'name'=>' China's news '
    ),
    array(
        'id'=>7,
        'pid'=>2,
        'name'=>' Overseas news '
    ),
    array(
        'id'=>8,
        'pid'=>6,
        'name'=>' State official news '
    ),
    array(
        'id'=>9,
        'pid'=>3,
        'name'=>' music '
    ),
    array(
        'id'=>10,
        'pid'=>3,
        'name'=>' The movie '
    ),
    array(
        'id'=>11,
        'pid'=>3,
        'name'=>' A novel '
    ),
    array(
        'id'=>12,
        'pid'=>9,
        'name'=>' The bell '
    ),
    array(
        'id'=>13,
        'pid'=>9,
        'name'=>' Pop music '
    ),
    array(
        'id'=>14,
        'pid'=>9,
        'name'=>' Classical music '
    ),
    array(
        'id'=>15,
        'pid'=>12,
        'name'=>' Popular ringtone '
    ),
    array(
        'id'=>16,
        'pid'=>12,
        'name'=>' Funny ringtone '
    ),
    array(
        'id'=>17,
        'pid'=>12,
        'name'=>'MP3 The bell '
    ),
    array(
        'id'=>18,
        'pid'=>17,
        'name'=>'128K'
    ),
    array(
        'id'=>19,
        'pid'=>8,
        'name'=>' Entertainment news '
    ),
    array(
        'id'=>20,
        'pid'=>11,
        'name'=>' Through the class '
    ),
    array(
        'id'=>21,
        'pid'=>11,
        'name'=>' Martial arts class '
    ),
);
?>

But the endless classification of class-related operations provided by those articles is a bit of a drag, and encapsulates database operations as well. If someone wants to use your class, they have to build a table like yours. That's disgusting. Because the project needs to be used, so I wrote 1 PHP infinite classification class (also called tree class), no database operation, only need to instantiate in the result set, which is the tree array. Then execute leaf method or navi method to get the desired results, look at the source code, after reading the corresponding template engine template recursive method.

<?php
/**
 * Tree  The tree class ( Infinite classification )
 *
 * @author Kvoid
 * @copyright http://kvoid.com
 * @version 1.0
 * @access public
 * @example
 *   $tree= new Tree($result);
 *   $arr=$tree->leaf(0);
 *   $nav=$tree->navi(15);
 */
class Tree {
    private $result;
    private $tmp;
    private $arr;
    private $already = array();
    /**
     *  The constructor 
     *
     * @param array $result  Tree data table result set 
     * @param array $fields  Tree data table field, array( classification id, The father id)
     * @param integer $root  The parent of the top-level classification id
     */
    public function __construct($result, $fields = array('id', 'pid'), $root = 0) {
        $this->result = $result;
        $this->fields = $fields;
        $this->root = $root;
        $this->handler();
    }
    /**
     *  Tree data table result set processing 
     */
    private function handler() {
        foreach ($this->result as $node) {
            $tmp[$node[$this->fields[1]]][] = $node;
        }
        krsort($tmp);
        for ($i = count($tmp); $i > 0; $i--) {
            foreach ($tmp as $k => $v) {
                if (!in_array($k, $this->already)) {
                    if (!$this->tmp) {
                        $this->tmp = array($k, $v);
                        $this->already[] = $k;
                        continue;
                    } else {
                        foreach ($v as $key => $value) {
                            if ($value[$this->fields[0]] == $this->tmp[0]) {
                                $tmp[$k][$key]['child'] = $this->tmp[1];
                                $this->tmp = array($k, $tmp[$k]);
                            }
                        }
                    }
                }
            }
            $this->tmp = null;
        }
        $this->tmp = $tmp;
    }
    /**
     *  Reverse recursive 
     */
    private function recur_n($arr, $id) {
        foreach ($arr as $v) {
            if ($v[$this->fields[0]] == $id) {
                $this->arr[] = $v;
                if ($v[$this->fields[1]] != $this->root) $this->recur_n($arr, $v[$this->fields[1]]);
            }
        }
    }
    /**
     *  Is recursive 
     */
    private function recur_p($arr) {
        foreach ($arr as $v) {
            $this->arr[] = $v[$this->fields[0]];
            if ($v['child']) $this->recur_p($v['child']);
        }
    }
    /**
     *  The menu   Multidimensional array 
     *
     * @param integer $id  classification id
     * @return array  Returns the branch, which by default returns the entire tree 
     */
    public function leaf($id = null) {
        $id = ($id == null) ? $this->root : $id;
        return $this->tmp[$id];
    }
    /**
     *  navigation  1 Dimensional array 
     *
     * @param integer $id  classification id
     * @return array  Returns a single line classification up to the top level classification 
     */
    public function navi($id) {
        $this->arr = null;
        $this->recur_n($this->result, $id);
        krsort($this->arr);
        return $this->arr;
    }
    /**
     *  scattered  1 Dimensional array 
     *
     * @param integer $id  classification id
     * @return array  return leaf Under all categories id
     */
    public function leafid($id) {
        $this->arr = null;
        $this->arr[] = $id;
        $this->recur_p($this->leaf($id));
        return $this->arr;
    }
}
?>

PHP infinite Classification in smarty:
$result=$db- > query (...) ; // Here the query results in the result set, note that the result set is an array
$tree= new Tree($result);
$arr=$tree- > leaf(0);
$nav=$tree- > navi(15);
$smarty- > assign (' arr ', $arr);
$smarty- > assign (' nav ', $nav);
$smarty- > display (' test html ');
Recursion in the smarty template is as follows:

<!-- navigation -->
<div id="navigator">
<{foreach $nav as $n}>
    <{if $n@iteration != $n@last}>
        <{$n.name}> ->
    <{else}>
        <{$n.name}>
    <{/if}>
<{/foreach}>
</div>
<!-- The tree menu -->
<div id="menu">
<{function name=menu}>
    <ul>
        <{foreach $data as $entry}>
            <li>
                <span><{$entry.name}></span> <{* Note that the field should be changed to its own field *}>
            <{if isset($entry.child)}>
                <{call name=menu data=$entry.child}>
            <{/if}>
            </li>
        <{/foreach}>
    </ul>
<{/function}>
<{call name=menu data=$arr}> <{* Notice here $arr That's the template variable *}>
</div>

Of course, you can also change the recursion method and feel free to use whatever tags you want. HTML+PHP hybrid recursive method here is not posted, I also do not bother to write, most hate mixing, looking disgusting, here recommended 1 jake predecessor SpeedPHP framework, because the default engine is smarty, my PHP infinite classification is fully compatible with SP framework. Similarly, jquery's treeview plug-in and drop-down menu plug-in are also perfectly supported.
By the way, Smarty's powerful caching capabilities are recommended. Caching is king.


Related articles: