您的位置:澳门402永利com > 澳门402永利com网络 > php树形结构数据存取实例类,php实现的树形结构

php树形结构数据存取实例类,php实现的树形结构

发布时间:2019-10-03 06:15编辑:澳门402永利com网络浏览(162)

     代码如下

    本文实例陈说了php实现的树形结构数据存取类。分享给大家供大家参谋。

    <?php
    /**
     * Tanphp framework
     *
     *
     * @category   Tanphp
     * @package    Data_structure
     * @copyright  Copyright (c) 2012 谭博  tanbo.name
     * @version    $Id: Tree.php 25024 2012-11-26 22:22:22 tanbo $
     */

    现实达成代码如下:

    /**
     * 树形结构数据存取类
     *
     * 用于对树形结构数据实行高效的存取
     *
     * @param array $arr 参数必得为规范的二维数组,包罗索引字段(id)与代表树形结构的字段(path),如example中所示
     *
     * @example <code>
     * $arr = array(
     *  array( 'id' => 1, 'name' => 'php', 'path' => '1' ),
     *  array( 'id' => 3, 'name' => 'php1', 'path' => '1-3' ),
     *  array( 'id' => 2, 'name' => 'mysql', 'path' => '2' ),
     *  array( 'id' => 6, 'name' => 'mysql1', 'path' => '2-6' ),
     *  array( 'id' => 7, 'name' => 'mysql2', 'path' => '2-7' ),
     *  array( 'id' => 5, 'name' => 'php11', 'path' => '1-3-5' ),
     *  array( 'id' => 4, 'name' => 'php2', 'path' => '1-4' ),
     *   );
     *  $cate = new Tree($arr);
     * 
     *  $data = $cate->getChild(2);
     * 
     *  print_r($data->toArray());
     * </code>
     *
     */

    复制代码 代码如下:

    class Tree
    {
        public  $_info;                             //节点音信
        public  $_child = array();                  //子节点
        private $_parent;                           //父节点
        private $_data;                             //当前操作的一时数据
        private static $_indexs         = array();  //全部节点的目录
        private static $_index_key      = 'id';     //索引键
        private static $_tree_key       = 'path';   //树形结构表明键
        private static $_tree_delimiter = '-';      //属性结构表明分割符
       
       
       
        /**
         * 构造函数
         *
         * @param array $arr
         * @param boole $force_sort 要是为真,将会强制对$arr 进行排序
         * @return void
         */
        public function __construct(array $arr = array(),  $force_sort=true)
        {
            if ($force_sort === true) {
                $arr=$this->_array_sort($arr, self::$_tree_key);
            }
            if (!empty($arr)) {
                $this->_init($arr);
            }
        }
       
        /**
         * 伊始存款和储蓄树形数据
         *
         * @param array $arr
         * @return void
         */
        private function _init(array $arr)
        {
            foreach ($arr as $item) {
                $path        = $item[self::$_tree_key];
                $paths       = explode(self::$_tree_delimiter, $path);
                $count_paths = count($paths);
                $parent_id   = isset($paths[$count_paths-2]) ? $paths[$count_paths-2] : NULL;
               
                if (   $count_paths>1                                   //假若有父级
                    && array_key_exists($parent_id, self::$_indexs)      //父级已经被存入索引
                    && self::$_indexs[$parent_id] instanceof Tree    //父级为Tree对象
                ) {
                    self::$_indexs[$parent_id]->addChild($item);
                } elseif ($count_paths == 1) {
                    $this->addChild($item);
                } else {
                    throw new Exception("path数据失实".var_export($item, true));
                }
               
            }
           
            //print_r(self::$_indexs);
        }
       
        /**
         * 增加子节点
         *
         * @param array $item
         * @return void
         */
        public function addChild(array $item, $parent = NULL)
        {
            $child          = new Tree();
            $child->_info   = $item;
            $child->_parent = $parent == NULL ? $this : $parent;
            $child->_parent->_child[] =  $child;
           
            $this->_addIndex($item, $child->_getSelf());
        }
       
        /**
         * 加多节点到目录
         *
         * @param array $item
         * @param mix $value
         * @return void
         */
        private function _addIndex(array $item, $value)
        {
            if (array_key_exists(self::$_index_key, $item) && is_int($item[self::$_index_key])) {
                self::$_indexs[$item[self::$_index_key]] = $value;
            } else {
                throw new Exception("id字段官样文章或许不为字符串");
            }
        }
       
       
        /**
         * 获取对和谐的引用
         *
         * @return Tree object quote
         */
        private function _getSelf()
        {
            return $this;
        }
       
        /**
         * 获取内定id的节点的子节点
         *
         * @param int $id
         * @return Tree object
         */
        public function getChild($id)
        {
            $data       = self::$_indexs[$id]->_child;
            $this->_data = $data;
            return $this;
        }
       
        /**
         * 获取内定id的节点的父节点
         *
         * @param int $id
         * @return Tree object
         */
        public function getParent($id)
        {
            $data = self::$_indexs[$id]->_parent;
            $this->_data = $data;
            return $this;
        }
       
        /**
         * 获取钦定id的节点的同级节点
         *
         * @param int $id
         * @return Tree object
         */
        public function getBrother($id)
        {
            $data = self::$_indexs[$id]->_parent->_child;
            $this->_data = $data;
            return $this;
        }
       
        /**
         * 将Tree对象转化为数组
         *
         * @param  object $object
         * @return array
         */
         public function toArray($obj = NULL)
         {
            $obj  = ($obj === NULL) ? $this->_data : $obj;
            $arr  = array();
            $_arr = is_object($obj) ? $this->_getBaseInfo($obj) : $obj;
           
            if (is_array($_arr)) {
                foreach ($_arr as $key => $val){
                   
                    $val = (is_array($val) || is_object($val)) ? $this->toArray($val) : $val;
                       
                    $arr[$key] = $val;
                }
            } else {
                throw new Exception("_arr不是数组");
            }
           
        
            return $arr;
        }
       
        /**
         * 过滤_parent等字段,防止形成非常循环
         *
         * @param object $obj
         * @return void
         */
        private function _getBaseInfo($obj)
        {
            $vars = get_object_vars($obj);
            $baseInfo['_info']  =  $vars['_info'];
            $baseInfo['_child'] =  $vars['_child'];
            return $baseInfo;
        }
       
        /**
         * 二维数组排序
         *
         * 根据钦命的键名对二维数组开展升序也许降序排列
         *
         * @param array  $arr 二维数组
         * @param string $keys
         * @param string $type 必须为 asc或desc
         * @throws 当参数违法时抛出卓殊
         * @return 重回排序好的数组
         */
        private function _array_sort(array $arr, $keys, $type = 'asc') {
            if (!is_string($keys)) {
                throw new Exception("不合法参数keys:参数keys的品种必须为字符串");
            }
       
            $keysvalue = $new_array = array();
            foreach ($arr as $k=>$v) {
                if (!is_array($v) || !isset($v[$keys])) {
                    throw new Exception("参数arr不是二维数组或arr子成分中不设有键'{$keys}'");
                }
                $keysvalue[$k] = $v[$keys];
            }
       
            switch ($type) {
                case 'asc':
                    asort($keysvalue);
                    break;
                case 'desc':
                    arsort($keysvalue);
                    break;
                default:
                    throw new Exception("违法参数type :参数type的值必须为 'asc' 或 'desc'");
            }
       
            reset($keysvalue);
            foreach ($keysvalue as $k=>$v) {
                $new_array[$k] = $arr[$k];
            }
            return $new_array;
        }
       
    }

    <?php
    /**
     * Tanphp framework
     *
     *
     * @category   Tanphp
     * @package    Data_structure
     * @version    $Id: Tree.php 25024 2012-11-26 22:22:22 tanbo $
     */
     
    /**
     * 树形结构数据存取类
     * 
     * 用于对树形结构数据进行高效的存取
     * 
     * @param array $arr 参数必得为标准的二维数组,包涵索引字段(id)与代表树形结构的字段(path),如example中所示
     * 
     * @example <code>
     * $arr = array(
     *  array( 'id' => 1, 'name' => 'php', 'path' => '1' ),
     *  array( 'id' => 3, 'name' => 'php1', 'path' => '1-3' ),
     *  array( 'id' => 2, 'name' => 'mysql', 'path' => '2' ),
     *  array( 'id' => 6, 'name' => 'mysql1', 'path' => '2-6' ),
     *  array( 'id' => 7, 'name' => 'mysql2', 'path' => '2-7' ),
     *  array( 'id' => 5, 'name' => 'php11', 'path' => '1-3-5' ),
     *  array( 'id' => 4, 'name' => 'php2', 'path' => '1-4' ),
     *   );
     *  $cate = new Tree($arr);
     *  
     *  $data = $cate->getChild(2);
     *  
     *  print_r($data->toArray());
     * </code>
     * 
     */
    class Tree
    {
        public  $_info;                             //节点音信
        public  $_child = array();                  //子节点
        private $_parent;                           //父节点
        private $_data;                             //当前操作的有时数据
        private static $_indexs         = array();  //全数节点的目录
        private static $_index_key      = 'id';     //索引键
        private static $_tree_key       = 'path';   //树形结构表明键
        private static $_tree_delimiter = '-';      //属性结构表明分割符
        
        /**
         * 构造函数
         * 
         * @param array $arr
         * @param boole $force_sort 假诺为真,将会强制对$arr 举行排序
         * @return void
         */
        public function __construct(array $arr = array(),  $force_sort=true)
        {
            if ($force_sort === true) {
                $arr=$this->_array_sort($arr, self::$_tree_key);
            }
            if (!emptyempty($arr)) {
                $this->_init($arr);
            }
        }
        
        /**
         * 初步存款和储蓄树形数据
         * 
         * @param array $arr
         * @return void
         */
        private function _init(array $arr)
        {
            foreach ($arr as $item) {
                $path        = $item[self::$_tree_key];
                $paths       = explode(self::$_tree_delimiter, $path);
                $count_paths = count($paths);
                $parent_id   = isset($paths[$count_paths-2]) ? $paths[$count_paths-2] : NULL;
                
                if (   $count_paths>1                                   //假设有父级
                    && array_key_exists($parent_id, self::$_indexs)      //父级已经被存入索引
                    && self::$_indexs[$parent_id] instanceof Tree    //父级为Tree对象
                ) {
                    self::$_indexs[$parent_id]->addChild($item);
                } elseif ($count_paths == 1) {
                    $this->addChild($item);
                } else {
                    throw new Exception("path数据失实".var_export($item, true));
                }
            }
            
            //print_r(self::$_indexs);
        }
        
        /**
         * 增添子节点
         * 
         * @param array $item
         * @return void
         */
        public function addChild(array $item, $parent = NULL)
        {
            $child          = new Tree();
            $child->_info   = $item;
            $child->_parent = $parent == NULL ? $this : $parent;
            $child->_parent->_child[] =  $child;
            
            $this->_addIndex($item, $child->_getSelf()); 
        }
        
        /**
         * 增加节点到目录
         * 
         * @param array $item
         * @param mix $value
         * @return void
         */
        private function _addIndex(array $item, $value)
        {
            if (array_key_exists(self::$_index_key, $item) && is_int($item[self::$_index_key])) {
                self::$_indexs[$item[self::$_index_key]] = $value;
            } else {
                throw new Exception("id字段海市蜃楼恐怕不为字符串");
            }
        }
        
        /**
         * 获取对团结的引用
         * 
         * @return Tree object quote
         */
        private function _getSelf()
        {
            return $this;
        }
        
        /**
         * 获取钦命id的节点的子节点
         * 
         * @param int $id
         * @return Tree object
         */
        public function getChild($id)
        {
            $data       = self::$_indexs[$id]->_child;
            $this->_data = $data;
            return $this;
        }
        
        /**
         * 获取钦点id的节点的父节点
         * 
         * @param int $id
         * @return Tree object
         */
        public function getParent($id)
        {
            $data = self::$_indexs[$id]->_parent;
            $this->_data = $data;
            return $this;
        }
        
        /**
         * 获取内定id的节点的同级节点
         *
         * @param int $id
         * @return Tree object
         */
        public function getBrother($id)
        {
            $data = self::$_indexs[$id]->_parent->_child;
            $this->_data = $data;
            return $this;
        }
        
        /**
         * 将Tree对象转化为数组
         * 
         * @param  object $object
         * @return array
         */
         public function toArray($obj = NULL)
         {
            $obj  = ($obj === NULL) ? $this->_data : $obj;
            $arr  = array();
            $_arr = is_object($obj) ? $this->_getBaseInfo($obj) : $obj;
            
            if (is_array($_arr)) {
                foreach ($_arr as $key => $val){
                    
                    $val = (is_array($val) || is_object($val)) ? $this->toArray($val) : $val;
                    $arr[$key] = $val;
                }
            } else {
                throw new Exception("_arr不是数组");
            }
         
            return $arr;
        }
        
        /**
         * 过滤_parent等字段,避防造成特别循环
         * 
         * @param object $obj
         * @return void
         */
        private function _getBaseInfo($obj)
        {
            $vars = get_object_vars($obj);
            $baseInfo['_info']  =  $vars['_info'];
            $baseInfo['_child'] =  $vars['_child'];
            return $baseInfo;
        }
        
        /**
         * 二维数组排序
         *
         * 根据钦赐的键名对二维数组开展升序恐怕降序排列
         *
         * @param array  $arr 二维数组
         * @param string $keys
         * @param string $type 必须为 asc或desc
         * @throws 当参数违规时抛出十三分
         * @return 再次来到排序好的数组
         */
        private function _array_sort(array $arr, $keys, $type = 'asc') {
            if (!is_string($keys)) {
                throw new Exception("非法参数keys:参数keys的花色必需为字符串");
            }
        
            $keysvalue = $new_array = array();
            foreach ($arr as $k=>$v) {
                if (!is_array($v) || !isset($v[$keys])) {
                    throw new Exception("参数arr不是二维数组或arr子元素中不设有键'{$keys}'");
                }
                $keysvalue[$k] = $v[$keys];
            }
        
            switch ($type) {
                case 'asc':
                    asort($keysvalue);
                    break;
                case 'desc':
                    arsort($keysvalue);
                    break;
                default:
                    throw new Exception("违法参数type :参数type的值必须为 'asc' 或 'desc'");
            }
        
            reset($keysvalue);
            foreach ($keysvalue as $k=>$v) {
                $new_array[$k] = $arr[$k];
            }
            return $new_array;
        }
    }
    ?>

    ?>

    盼望本文所述对我们的PHP程序设计有所帮忙。

    您恐怕感兴趣的小说:

    • php Infiniti级分类,一级轻松的非常级分类,帮忙出口树状图
    • PHP+Mysql树型结构(Infiniti分类)数据库设计的2种艺术实例
    • PHP超牛逼无限极分类生成树方法
    • php Infiniti分类的树类代码
    • PHPInfiniti分类(树形类)
    • php+mysql达成Infiniti级分类 | 树型显示分类关系
    • php完毕从ftp服务器上下载文件树到本地Computer的前后相继
    • phpInfiniti分类且辅助出口树状图的详尽介绍
    • 用PHP完毕多元树型菜单
    • php生成Infiniti栏目树

    本文由澳门402永利com发布于澳门402永利com网络,转载请注明出处:php树形结构数据存取实例类,php实现的树形结构

    关键词: