PHP infinitus classification implementation (no recursion), php Recursion

Source: Internet
Author: User

PHP infinitus classification implementation (no recursion), php Recursion

Infinitus classification is often used in development, such as Department structure and document classification. The difficulties of infinitus classification are "output" and "query", for example

  • Output the document category in the <ul> List format;
  • Search for articles contained in all categories under category.
1. Implementation Principle

Several common implementation methods are introduced in the article "how to implement an unlimited classification", which have their own advantages and disadvantages. The data structure of "improved forward traversal Tree" is easy to output and query, but it is complicated in terms of mobile classification and general understanding.

2. Data Structure
Id Fid Title
1 0 China
2 1 Jiangsu
3 1 Anhui Province
4 8 Jiangyin
5 3 Wuhu
6 3 Hefei
7 3 Bengbu
8 2 Wuxi
<? Php $ list = array ('id' => 1, 'fid' => 0, 'title' => 'China '), array ('id' => 2, 'fid' => 1, 'title' => 'jiangsu '), array ('id' => 3, 'fid' => 1, 'title' => 'anhui '), array ('id' => 4, 'fid' => 8, 'title' => 'jiangyin '), array ('id' => 5, 'fid' => 3, 'title' => 'wuhu '), array ('id' => 6, 'fid' => 3, 'title' => 'hefei '), array ('id' => 7, 'fid' => 3, 'title' => 'bengbu '), array ('id' => 8, 'fid' => 8, 'title' => 'wuxi ');?>

Each category is connected by its parent class id (fid) to form a classification tree. It is worth noting that the fid of classification A cannot be the id of its subclass.

When using this data structure for output, the most common algorithm is "recursion". friends familiar with the PHP language certainly know that PHP is not good at recursion and has a limited number of recursion times (about 100 times, operating System and configuration vary ).

Since all recursion functions can be implemented cyclically, this article has compiled a set of functions for "infinite" classification based on the characteristics of PHP language, which is more efficient than Recursive Implementation.

3. Output ul List format

Output the above data as the following HTML

<Ul> <li class = "first-child"> <div> Jiangsu </div> <ul> <li class = "first-child last-child"> <div> wuxi </div> <ul> <li class = "first-child last-child"> <div> Jiangyin </div> </li> </ul> </li> </ul> </li> <li class = "last-child"> <div> Anhui </div> <ul> <li class = "first-child"> <div> Wuhu </div> </li> <div> Hefei </div> </li> <li class = "last-child"> <div> bengbu </div> </li> </ul>

This HTML structure is very convenient for front-end use (using JavaScript and CSS to construct a foldable tree. The specific implementation procedure is as follows:

<ul><?php get_tree_ul($list, 1); ?></ul>
4. Output option List format
<Select> <option value = "2"> Jiangsu </option> <option value = "8"> & nbsp; wuxi </option> <option value = "4"> & nbsp; jiangyin </option> <option value = "3"> Anhui </option> <option value = "5"> & nbsp; wuhu </option> <option value = "6"> & nbsp; hefei </option> <option value = "7"> & nbsp; Bengbu </option> </select>

The specific implementation procedure is as follows:

<Select> <? Php // get_tree_option () returns an array and adds a "depth" (depth) column to each element. You can directly output $ options = get_tree_option ($ list, 1 ); foreach ($ options as $ op) {echo '<option value = "'. $ op ['id']. '"> '. str_repeat ("", $ op ['Demo'] * 4 ). $ op ['title']. '<;/option>' ;}?> <;/Select>
5. Search for all subclasses of a category
<? Php $ children = get_tree_child ($ list, 0); echo implode (',', $ children); // output:,?>
6. Search for all parent classes of a category
<?php    $children = get_tree_parent($list, 4);    echo implode(',', $children);    //8, 2, 10?>
7. Related functions
<?phpfunction get_tree_child($data, $fid) {    $result = array();    $fids = array($fid);    do {        $cids = array();        $flag = false;        foreach($fids as $fid) {            for($i = count($data) - 1; $i >=0 ; $i--) {                $node = $data[$i];                if($node['fid'] == $fid) {                    array_splice($data, $i , 1);                    $result[] = $node['id'];                    $cids[] = $node['id'];                    $flag = true;                }            }        }        $fids = $cids;    } while($flag === true);    return $result;}function get_tree_parent($data, $id) {    $result = array();    $obj = array();    foreach($data as $node) {        $obj[$node['id']] = $node;    }        $value = isset($obj[$id]) ? $obj[$id] : null;        while($value) {        $id = null;        foreach($data as $node) {            if($node['id'] == $value['fid']) {                $id = $node['id'];                $result[] = $node['id'];                break;            }        }        if($id === null) {            $result[] = $value['fid'];        }        $value = isset($obj[$id]) ? $obj[$id] : null;    }    unset($obj);    return $result;}function get_tree_ul($data, $fid) {    $stack = array($fid);    $child = array();    $added_left = array();    $added_right= array();    $html_left     = array();    $html_right    = array();    $obj = array();    $loop = 0;    foreach($data as $node) {        $pid = $node['fid'];        if(!isset($child[$pid])) {            $child[$pid] = array();        }        array_push($child[$pid], $node['id']);        $obj[$node['id']] = $node;    }    while (count($stack) > 0) {            $id = $stack[0];        $flag = false;        $node = isset($obj[$id]) ? $obj[$id] : null;        if (isset($child[$id])) {            $cids = $child[$id];            $length = count($cids);            for($i = $length - 1; $i >= 0; $i--) {                array_unshift($stack, $cids[$i]);            }            $obj[$cids[$length - 1]]['isLastChild'] = true;            $obj[$cids[0]]['isFirstChild'] = true;            $flag = true;        }        if ($id != $fid && $node && !isset($added_left[$id])) {            if(isset($node['isFirstChild']) && isset($node['isLastChild']))  {                $html_left[] = '<li class="first-child last-child">';            } else if(isset($node['isFirstChild'])) {                $html_left[] = '<li class="first-child">';            } else if(isset($node['isLastChild'])) {                $html_left[] = '<li class="last-child">';            } else {                $html_left[] = '<li>';            }                        $html_left[] = ($flag === true) ? "<div>{$node['title']}</div><ul>" : "<div>{$node['title']}</div>";            $added_left[$id] = true;        }            if ($id != $fid && $node && !isset($added_right[$id])) {            $html_right[] = ($flag === true) ? '</ul></li>' : '</li>';            $added_right[$id] = true;        }        if ($flag == false) {            if($node) {                $cids = $child[$node['fid']];                for ($i = count($cids) - 1; $i >= 0; $i--) {                    if ($cids[$i] == $id) {                        array_splice($child[$node['fid']], $i, 1);                        break;                    }                }                 if(count($child[$node['fid']]) == 0) {                    $child[$node['fid']] = null;                }            }            array_push($html_left, array_pop($html_right));            array_shift($stack);        }        $loop++;        if($loop > 5000) return $html_left;    }    unset($child);    unset($obj);    return implode('', $html_left);}function get_tree_option($data, $fid) {    $stack = array($fid);    $child = array();    $added = array();    $options = array();    $obj = array();    $loop = 0;    $depth = -1;    foreach($data as $node) {        $pid = $node['fid'];        if(!isset($child[$pid])) {            $child[$pid] = array();        }        array_push($child[$pid], $node['id']);        $obj[$node['id']] = $node;    }    while (count($stack) > 0) {            $id = $stack[0];        $flag = false;        $node = isset($obj[$id]) ? $obj[$id] : null;        if (isset($child[$id])) {            for($i = count($child[$id]) - 1; $i >= 0; $i--) {                array_unshift($stack, $child[$id][$i]);            }            $flag = true;        }        if ($id != $fid && $node && !isset($added[$id])) {            $node['depth'] = $depth;            $options[] = $node;            $added[$id] = true;        }        if($flag == true){            $depth++;        } else {            if($node) {                for ($i = count($child[$node['fid']]) - 1; $i >= 0; $i--) {                    if ($child[$node['fid']][$i] == $id) {                        array_splice($child[$node['fid']], $i, 1);                        break;                    }                }                 if(count($child[$node['fid']]) == 0) {                    $child[$node['fid']] = null;                    $depth--;                }            }            array_shift($stack);        }        $loop++;        if($loop > 5000) return $options;    }    unset($child);    unset($obj);    return $options;}?>

Php recursion (infinitus classification)

Foreach itself is equivalent to judgment. When the $ arr array is not empty, foreach will traverse and recursively access the child node, but for the leaf node, the $ arr array is empty, it will not be foreach at all, and return directly at this time. Understand?

Php recursion problem, want to display the data according to the infinitus classification Style

First, decode the json into an array. Use the json_decode function to add the second parameter. Otherwise, it will return an object. The next step is recursive. This is the simplest recursion. You only need to traverse them one by one.
The complete code is as follows:
$ Data = json_decode ($ str, true); $ options = getChildren ($ data); function getChildren ($ parent, $ deep = 0) {foreach ($ parent as $ row) {$ data [] = array ("id" => $ row ['id'], "name" => $ row ['name'], "pid" => $ row ['parentid'], 'deep '=> $ deep); if ($ row ['childs']) {$ data = array_merge ($ data, getChildren ($ row ['childs '], $ deep + 1) ;}return $ data ;}?> <Select name = "" id = ""> <? Php foreach ($ options as $ row) {?> <Option value = "<? Php echo $ row ['id']?> "> <? Php echo str_pad ("", $ row ['deep '] * 3, "-", STR_PAD_RIGHT);?> <? Php echo $ row ['name'];?> </Option> <? Php }?> </Select>
The above code has passed the test as follows:




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.