如何创建多级别类别层次结构(类别树) - codeigniter

时间:2012-01-24 09:30:53

标签: php mysql categories

我想简单地从mysql

创建一个多级类别层次结构

分类表:

________________________________________________________________________
| id              |  parent_id     | name
————————————————————————————————————————————————————————————————————————
| 1               |  0             | Root
| 2               |  1             | Sub category of root
| 3               |  0             | category 1
| 4               |  3             | sub category of category 1
| 5               |  4             | sub category of first sub category of category 1
————————————————————————————————————————————————————————————————————————

PHP

public function getCategoryTree($level = 0) {
    $rows = $this->db
            ->select(‘id,parent_id,name’)
            ->where(‘parent_id’, $level)
            ->get(‘categories’)
            ->result();

    if (count($rows) > 0) {
        foreach ($rows as $row) {
            $rows = $this->getCategoryTree($row->id);
        }
    }
  //return $rows;
}


echo $rows;

// output will be show as string so i have to return this string in a variable

Root
—Sub category of root
category 1
—sub category of category 1
——sub category of first sub category of category 1

5 个答案:

答案 0 :(得分:6)

您的代码中最大的问题是您在foreach循环中覆盖了$rows

此外,使用递归解决方案,就像你已经去过的那样,跟踪从函数/方法的内部调用返回的内容非常重要。

另外,我添加了一个订单,以确保首先显示根类别。

protected function getCategoryTree($level = 0, $prefix = '') {
    $rows = $this->db
        ->select('id,parent_id,name')
        ->where('parent_id', $level)
        ->order_by('id','asc')
        ->get('categories')
        ->result();

    $category = '';
    if (count($rows) > 0) {
        foreach ($rows as $row) {
            $category .= $prefix . $row->name . "\n";
            // Append subcategories
            $category .= $this->getCategoryTree($row->id, $prefix . '-');
        }
    }
    return $category;
}

public function printCategoryTree() {
    echo $this->getCategoryTree();
}

答案 1 :(得分:0)

试试以下......

<?php 
$sql = "SELECT id, name, parent_id FROM category ORDER BY parent_id, id";
$results = mysqli_query($con,$sql) or die(mysqli_error()) ;
if($results)
{
    while($result = mysqli_fetch_array($results))
    {
        $category['categories'][$result['id']] = $result; 
        $category['parent_cats'][$result['parent_id']][] = $result['id']; 
    }
}
?>

<?php 
function getCategories($parent, $category) 
{
    $html = "";
    if (isset($category['parent_cats'][$parent]))
    {
        $html .= "<ul>\n";
        foreach ($category['parent_cats'][$parent] as $cat_id)
        {
            if (!isset($category['parent_cats'][$cat_id]))
            {
              $html .= "<li>".$category['categories'][$cat_id]['name']."</li> \n";
            }
            if (isset($category['parent_cats'][$cat_id]))
            {
              $html .= "<li>". $category['categories'][$cat_id]['name'] . " \n";
              $html .= getCategories($cat_id, $category);
              $html .= "</li> \n";
            }
        }
        $html .= "</ul> \n";
    }
    return $html;
}
?>

现在调用Recursive函数来显示层次结构中的所有类别:

<?php echo $data['category'] = getCategories(0, $category);?>

详情info

答案 2 :(得分:0)

<?php

     $servername = "localhost";
    $username = "root";
    $password = "";


    $conn = new mysqli($servername, $username, $password,'test');


 if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
} 




function getCategoryTree($level = 0, $prefix = '') {


 $category = '';
$sql = "SELECT * FROM category WHERE parent_id = $level ORDER BY id asc";
$result = $GLOBALS['conn']->query($sql);

if ($result->num_rows > 0) {
    // output data of each row
    while($row = $result->fetch_assoc()) {

         $category .= $prefix . $row['name'] . "<br/>";
         $category .= getCategoryTree($row['id'], $prefix . '-');
    }
}
return $category;
}

function printCategoryTree() {
    echo getCategoryTree();
}

printCategoryTree();


?>

答案 3 :(得分:0)

此表:

CREATE TABLE `categories` (
  `id` int(11) NOT NULL,
  `parent_id` int(11) NOT NULL DEFAULT '0',
  `name` varchar(100) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

首先创建config.php。

<?php

    $servername = "localhost";
    $username = "root";
    $password = "";


    $db = new mysqli($servername, $username, $password,'test');


 if ($db->connect_error) {
    die("Connection failed: " . $db->connect_error);
} 
?>

然后创建category.php。

<?php 
    require 'config.php'; 

    if(isset($_POST['submit']))
    { 
        $parent_id=$_POST['parent_id']; 
        $name=$_POST['name']; 
        global $db;
        $db->query("INSERT INTO categories (name,parent_id) VALUES('$name','$parent_id') ") or die(mysql_error());          
    } 

    function categoryTree($parent_id = 0, $sub_mark = ''){
    global $db;
    $query = $db->query("SELECT * FROM categories WHERE parent_id = '$parent_id' ORDER BY name ASC ");

    if($query->num_rows > 0){
        while($row = $query->fetch_assoc()){
            echo '<option value="'.$row['id'].'">'.$sub_mark.$row['name'].'</option>';
            categoryTree($row['id'], $sub_mark.'---');
        }
    }
}

?> 
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<form action="" method="POST"><select name="parent_id">
    <option value="0">Select Category</option><?php categoryTree(); ?>
    </select>
    Category : <input name="name" type="text" /> 
    <input name="submit" type="submit" value="Submit" /></form>
</body>
</html>

答案 4 :(得分:0)

Create a file add.php

<script type="text/javascript" src="<?=$this->config->item('js_path')?>jquery-3.2.1.js"></script>
<script type="text/javascript" src="<?=$this->config->item('js_path')?>jquery.validate.min.js"></script>

<link href="http://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/css/toastr.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.2.0/jquery-confirm.min.css" rel="stylesheet" type="text/css" />

<script src="http://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.0.2/js/toastr.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.2.0/jquery-confirm.min.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="<?=$this->config->item('css_path')?>bootstrap.min.css"> 

<html>
<head>
<div id="myDropdown" class="dropdown-content">
    <a href="<?php echo base_url('Category/add') ?>">Category Form</a>
    <a href="<?php echo base_url('Category/index') ?>">User Listing</a>
  </div>
    <div align="center"><h3>Category Form</h3></div>
</head>
<body>
    <form id="signup_form" method="post" action="" enctype="multipart/form-data" >

        <table border="1" align="center" width="450">
            <tr>
                <td>Category Name</td>
                <td>
                   <input type="text" id="category_name" name="category_name" onkeypress="return isChar(event)" value="<?php echo !empty($editRecord[0]->category_name) ? $editRecord[0]->category_name :'' ?>" class="form-control" placeholder="Category Name">
                </td>
            </tr>
            <tr>
                <td>Category</td>
                <td>
                   <select class="form-control" id="parent_id" name="parent_id">
                        <option value="">Select Category</option>
                            <?php if(!empty($result)){ ?>

                            <?php foreach($result as $category){ ?>
                                <option value="<?php echo $category['id'] ?>"><?php echo $category['category_name']; ?></option>
                               <?php
                                   if(!empty($category['subs'])) { 

                                       foreach ($category['subs'] as $sub)  {
                                        ?>
                                        <option value="<?php echo $category['id'] ?>"><?php echo '--' . $sub['category_name'] ?></option>

                                       <?php    
                                       }
                                    }
                               ?>
                            <?php } }else{
                            echo '<li><a href="javascript:void();" style="color:red;">Sorry no category found.</a></li>';
                            } ?>
                   </select>
                </td>
            </tr>           
            <tr collspan="2">
                <td align="center">
                    <input type="submit" name="submit" value="submit">
                </td>
            </tr>

        </table>
        <input type="hidden" name="id" id="id" value="<?= !empty($editRecord[0]->id)?$editRecord[0]->id:'';?>" >
    </form>

</body>
</html>
<script type="text/javascript">
    $("#signup_form").validate({
        onkeyup: false,
        rules:{
            category_name: {
                required: true
            },

        },
        messages:{
            category_name:{
                required: "Category Name cannot be blank.",
            },           
        },
    });

    function isChar(evt)
    {
         evt = (evt) ? evt : window.event;
            var charCode = (evt.which) ? evt.which : evt.keyCode;
            if (charCode >=48 && charCode <= 57) {
                return false;
            }
            return true;
    }


 $('#signup_form').submit(function(e) {
    /* Populate data to state dropdown */
    var form = $(this);
        e.preventDefault();
            $.ajax({
                type: "POST",
                url: "<?php echo base_url('Category/insert_record/');?>",
                data: form.serialize(),
                success:function(data){
                    //console.log(data);
                    $('#parent_id').html('<option value="">Select Category</option>'); 
                    var dataObj = jQuery.parseJSON(data);
                    if(dataObj){
                        $(dataObj).each(function(){
                            var option = $('<option />');
                            option.attr('value', this.id).text(this.category_name);           
                            $('#parent_id').append(option);
                        });
                    }
                    toastr.success('Category Added Successfully.', 'Success Alert', {timeOut: 5000});
                    $('#signup_form').trigger("reset");
                },
                error: function() { toastr.danger('Something went worng.', 'Danger Alert', {timeOut: 5000}); }
            }); 
    });
</script>

创建文件列表。php

<link rel="stylesheet" type="text/css" href="<?=$this->config->item('css_path')?>bootstrap.min.css"> 
<script type="text/javascript" src="<?=$this->config->item('js_path')?>jquery-3.2.1.js"></script>
<html>
<body>
<table border="2" align="center">

    <tr>
        <td width="30">#</td>
        <td>Product Name</td>
        <td>Price</td>
        <td>Category Name</td>
        <td>Sub_Category Name</td>
        <td>Image</td>
        <td>Action</td>

    </tr>

    <?php 
    foreach($products as $product)
    {
        ?>
        <tr>
            <td><?php echo $product->id;?></td>
            <td><?php echo $product->product_name;?></td>
            <td><?php echo $product->price;?></td>
            <td><?php echo $product->category_name;?></td>
            <td><?php echo $product->subcategory_name;?></td>


            <td><img style="width: 50px;height: 40px;" src="<?php echo base_url('uploads/'. $product->image);?>" /></td>

            <td>
                <a href="<?php echo base_url('Category/edit_record/')?><?php echo $product->id?>">Edit</a>
                <span class='delete' id='del_<?php echo $product->id; ?>'>Delete</span>
            </td>
        </tr>

        <?php
    }
   ?>   
   <tr>
    <td colspan="2"><a href="<?php echo base_url('Category/add')?>">Add new</a></td>



   </tr>
   </table>
   </body>
   </html>

<script type="text/javascript">

    $(document).ready(function(){

        $('.delete').click(function(){
        var el = this;
        var id = this.id;
        var splitid = id.split("_");

         // Delete id
        var deleteid = splitid[1];

         // AJAX Request
        $.ajax({
            url: "<?php echo base_url('Category/delete/');?>",
            type: 'POST',
            data: { id:deleteid },
            success: function(response){

               // Removing row from HTML Table
                $(el).closest('tr').css('background','tomato');
                $(el).closest('tr').fadeOut(800, function(){ 
                $(this).remove();
                    });
                }
            });

        });
    });
</script>
<style type="text/css">
    .panel-heading a{float: right;}
    #importFrm{margin-bottom: 20px;display: none;}
    #importFrm input[type=file] {display: inline;}
</style>

现在创建category_model     

class Category_model extends CI_Model
{

    function ordered_menu($array,$parent_id = 0)
    { 
        $temp_array = array();
        foreach($array as $element)
        {
            if($element['parent_id']==$parent_id)
            {
                $element['subs'] = $this->ordered_menu($array,$element['id']);
                $temp_array[] = $element;
            }
        }
        return $temp_array;
    }

    public function get_categories()
    {
        $this->db->select('id,category_name');
        $result = $this->db->get('categories');
        return $result->result();
    }

    public function get_category(){
        $this->db->select('id,category_name');
        $this->db->where('parent_id',0);
        $result = $this->db->get('categories');
        return $result->result();
    }

    function getSubs($params = array())
    {
        $this->db->select('id, category_name,parent_id');
        $this->db->from('categories');

        if(array_key_exists("conditions",$params)){
            foreach ($params['conditions'] as $key => $value) {
                if(strpos($key,'.') !== false){
                    $this->db->where($key,$value);
                }else{
                    $this->db->where('categories.'.$key,$value);
                }
            }
        }       
        $query = $this->db->get();
        $result = ($query->num_rows() > 0)?$query->result_array():FALSE;

        return $result;
    }

    public function get_products()
    {
        $this->db->select('products.id,category_name,parent_id,product_name,price,subcategory_name,image');
        $this->db->from('categories');
        $this->db->join('products','products.category_id = categories.parent_id');
        $this->db->join('sub_categories','sub_categories.cat_id = categories.id');
        $result=$this->db->get();
        return $result->result();
    }

    public function get_detail($id){
        $this->db->select('*');
        $this->db->where('id',$id);
        $result = $this->db->get('products');
        return $result->result();
    }
}
?>

创建类别控制器。

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Category extends CI_Controller {

        public function __construct()
        {
            parent:: __construct();
            $this->load->model('category_model');
            $this->load->model('Common_model');
        }

        public function index()
        {
            $data['products'] = $this->category_model->get_products();
            $this->load->view('category/list',$data);
        }

        public function add()
        {

            $data['categories']=$this->db->get('categories')->result_array();
            $data['result']=$this->category_model->ordered_menu( $data['categories'],0);

            $this->load->view('category/add',$data);
        }

        public function insert_record()
        {
            $this->load->library('form_validation');

            if($this->input->server('REQUEST_METHOD') == 'POST')
            {
                $this->form_validation->set_rules('category_name','Category Name','trim|required');

                if($this->form_validation->run() == FALSE)
                {
                    $this->load->view('category/add');
                }
                else
                {
                    $post_array = $this->input->post();
                    if($post_array['parent_id'] == '')
                    {
                        $data = array(
                        'category_name' => $post_array['category_name'],
                        'parent_id' => 0,
                        );
                    }else{
                        $data = array(
                            'category_name' => $post_array['category_name'],
                            'parent_id' => $post_array['parent_id'],                        
                        );
                    }

                    $inser_data = $this->Common_model->insert('categories',$data);

                    if(!empty($inser_data))
                    {
                        $allcategory = $this->category_model->get_categories();

                        foreach ($allcategory as $value) {
                            $cat[] = $value;  
                        }
                        echo json_encode($cat);
                    }
                }
            }

        }  

        public function add_product()
        {
            $data['categories']=$this->category_model->get_category();  
            $this->load->view('category/add_product',$data);
        }

        public function get_subcatries(){

            $subcat = array();
            $category= $this->input->post('parent_id');
            if($category){
                $con['conditions'] = array('parent_id'=>$category);
                $subcat = $this->category_model->getSubs($con);
            }

            echo json_encode($subcat);
        }

        public function insert()
        {
            $config['upload_path'] = 'uploads/';
            $config['allowed_types'] = '*';
            $config['max_filename'] = '255';
            $config['encrypt_name'] = TRUE;
            $config['max_size'] = '1024'; //1 MB

            if (isset($_FILES['file']['name'])) 
            {
                if (0 < $_FILES['file']['error']) 
                {
                    echo 'Error during file upload' . $_FILES['file']['error'];
                } else 
                {
                    if (file_exists('uploads/' . $_FILES['file']['name'])) 
                    {
                        echo 'File already exists : uploads/' . $_FILES['file']['name'];
                    } 
                    else 
                    {
                        $this->load->library('upload', $config);

                        if (!$this->upload->do_upload('file')) {
                            echo $this->upload->display_errors();
                        } else {
                            $photo =  $_FILES['file']['name'];
                        }
                    }
                }
            } else {
                echo 'Please choose a file';
            }
            $this->load->library('form_validation');

            if($this->input->server('REQUEST_METHOD') == 'POST')
            {
                $this->form_validation->set_rules('product_name','Product Name','trim|required');
                $this->form_validation->set_rules('price','Price','trim|required');
                $this->form_validation->set_rules('category_id','Category Name','trim|required');

                if($this->form_validation->run() == FALSE)
                {
                    $this->load->view('category/add');
                }
                else
                {
                    $post_array = $this->input->post();

                    if($post_array['subcat_id'] == '')
                    {
                        $data = array(
                            'product_name' => $post_array['product_name'],
                            'price' => $post_array['price'],
                            'category_id' => $post_array['category_id'],
                            'image' => $photo,
                            'subcat_id' => 0,
                        );
                    }else{
                        $data = array(
                            'product_name' => $post_array['product_name'],
                            'price' => $post_array['price'],
                            'category_id' => $post_array['category_id'],
                            'image' => $photo,
                            'subcat_id' => $post_array['subcat_id'],                        
                        );
                    }

                    $inser_data = $this->Common_model->insert('products',$data);

                    if(!empty($inser_data))
                    {
                        echo '1';
                    }else{
                        echo '0';
                    }
                }
            }

        }

        public function edit_record()
        {

            $id = $this->uri->segment(3);
            $result = $this->category_model->get_detail($id);
            if(empty($result))
            {
                redirect('Category/');
            }
            $data['editRecord'] = $result;
            $this->load->view('category/add_product',$data);

        }
    }
    ?>

此创建用于添加类别的产品。

<script type="text/javascript" src="<?=$this->config->item('js_path')?>jquery-3.2.1.js"></script>
<script type="text/javascript" src="<?=$this->config->item('js_path')?>jquery.validate.min.js"></script>

<link href="http://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/css/toastr.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.2.0/jquery-confirm.min.css" rel="stylesheet" type="text/css" />

<script src="http://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.0.2/js/toastr.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.2.0/jquery-confirm.min.js" type="text/javascript"></script>

<link rel="stylesheet" type="text/css" href="<?=$this->config->item('css_path')?>bootstrap.min.css"> 

<html>
<head>
<div id="myDropdown" class="dropdown-content">
    <a href="<?php echo base_url('Category/add') ?>">Category Form</a>
    <a href="<?php echo base_url('Category/index') ?>">Product Listing</a>
  </div>
    <div align="center"><h3>Product Form</h3></div>
</head>
<body>
    <form id="product_form" method="post" action="" enctype="multipart/form-data" >

        <table border="1" align="center" width="450">
            <tr>
                <td>Product Name</td>
                <td>
                   <input type="text" id="product_name" name="product_name" onkeypress="return isChar(event)" value="<?php echo !empty($editRecord[0]->product_name) ? $editRecord[0]->product_name :'' ?>" class="form-control" placeholder="Product Name">
                </td>
            </tr>

            <tr>
                <td>Price</td>
                <td>
                   <input type="text" id="price" name="price" onkeypress="return isNumber(event)" value="<?php echo !empty($editRecord[0]->price) ? $editRecord[0]->price :'' ?>" class="form-control" placeholder="Price">
                </td>
            </tr>

            <tr>
                <td>Category</td>
                <td>
                   <select class="form-control" id="category_id" name="category_id">
                        <option value="">Select Category</option>

                            <?php if(!empty($categories)){ ?>

                            <?php foreach($categories as $category){ ?>
                                <option value="<?php echo $category->id ?>"><?php echo $category->category_name; ?></option>

                            <?php } }else{
                            echo '<li><a href="javascript:void();" style="color:red;">Sorry no category found.</a></li>';
                            } ?>
                   </select>
                </td>
            </tr>      
            <tr>
                <td>Sub Category</td>
                <td>
                   <select class="form-control" id="subcat_id" name="subcat_id">
                        <option value="">Select Sub Category</option>

                   </select>
                </td>
            </tr>    
            <tr>
                <td>Image</td>
                <td>
                    <input type="file" name="file" id="file" value="<?php echo !empty($editRecord[0]->file) ? $editRecord[0]->file :'' ?>">
                </td>
            </tr>

            <tr collspan="2">
                <td align="center">
                    <input type="submit" name="submit" value="submit">
                </td>
            </tr>

        </table>
        <input type="hidden" name="id" id="id" value="<?= !empty($editRecord[0]->id)?$editRecord[0]->id:'';?>" >
    </form>

</body>
</html>
<script type="text/javascript">

    $("#product_form").validate({
        onkeyup: false,
        rules:{
            product_name: {
                required: true,
            },
            price: {
                required: true,
            },
            category_id:{
                required: true,               
            }      
        },
        messages:{
            product_name:{
                required: "Product Name cannot be blank.",
            },
            price:{
                required: "Price cannot be blank.",
            },
            category_id:{
                required: "Category Name cannot be blank.",
            }
        },
    });

    function isChar(evt)
    {
         evt = (evt) ? evt : window.event;
            var charCode = (evt.which) ? evt.which : evt.keyCode;
            if (charCode >=48 && charCode <= 57) {
                return false;
            }
            return true;
    }

    function isNumber(evt)
    {
         evt = (evt) ? evt : window.event;
            var charCode = (evt.which) ? evt.which : evt.keyCode;
            if (charCode > 32 && (charCode < 48 || charCode > 57)) {
                return false;
            }
            return true;
    }

    $(document).ready(function(){

        $('#category_id').on('change',function(){
            var category_id = $(this).val();
            if(category_id){
                $.ajax({
                    type:'POST',
                    url:'<?php echo base_url('Category/get_subcatries'); ?>',
                    data:'parent_id='+category_id,
                    success:function(data){
                        $('#subcat_id').html('<option value="">Select Subcategory</option>'); 
                        var dataObj = $.parseJSON(data);
                        if(dataObj){
                            $(dataObj).each(function(){
                                var option = $('<option />');
                                option.attr('value', this.id).text(this.category_name);           
                                $('#subcat_id').append(option);
                            });
                        }else{
                            $('#subcat_id').html('<option value="">Subcategory not available</option>');
                        }
                    }
                }); 
            }else{
                $('#subcat_id').html('<option value="">Select Category first</option>'); 
            }
        });

        $('#product_form').submit(function(e) {

            var id = $('#id').val();
            e.preventDefault();

            if(id == '')
            {
                url = "<?php echo base_url('Category/insert/');?>" + $("#id").val();
                $.ajax({
                    url:url,
                    type:"post",
                    data:new FormData(this),
                    processData:false,
                    contentType:false,
                    cache:false,
                    async:false,
                    success: function(data){
                        if (data == 1) {    
                        //setTimeout(function(){document.location.href = "index"},500);                
                        toastr.success('Recored Added Successfully.', 'Success Alert', {timeOut: 5000});
                        }
                        $('#product_form').trigger("reset");
                    },
                    error: function() { alert("Error posting feed."); }
                });
            }
            else
            {           
                url = "<?php echo base_url('Category/update/');?>" + $("#id").val();
                $.ajax({
                    url:url,
                    type:"post",
                    data:new FormData(this),
                    processData:false,
                    contentType:false,
                    cache:false,
                    async:false,
                    success: function(data){
                        if (data == 1) {                    
                            toastr.success('Recored Updated Successfully.', 'Success Alert', {timeOut: 5000});
                            setTimeout(function(){document.location.href = "index"},5000);
                        }
                        //$('#signup_form').trigger("reset");
                    },
                    error: function() { alert("Error posting feed."); }
                });
            }

        });
    });

</script>