php实现的树形结构数据存取类实例
本文实例讲述了php实现的树形结构数据存取类。分享给大家供大家参考。
具体实现代码如下:
<?php
/**
*Tanphpframework
*
*
*@category Tanphp
*@package Data_structure
*@version $Id:Tree.php250242012-11-2622:22:22tanbo$
*/
/**
*树形结构数据存取类
*
*用于对树形结构数据进行快速的存取
*
*@paramarray$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=newTree($arr);
*
* $data=$cate->getChild(2);
*
* print_r($data->toArray());
*</code>
*
*/
classTree
{
public $_info; //节点信息
public $_child=array(); //子节点
private$_parent; //父节点
private$_data; //当前操作的临时数据
privatestatic$_indexs =array(); //所有节点的索引
privatestatic$_index_key ='id'; //索引键
privatestatic$_tree_key ='path'; //树形结构表达键
privatestatic$_tree_delimiter='-'; //属性结构表达分割符
/**
*构造函数
*
*@paramarray$arr
*@paramboole$force_sort如果为真,将会强制对$arr进行排序
*@returnvoid
*/
publicfunction__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);
}
}
/**
*初始存储树形数据
*
*@paramarray$arr
*@returnvoid
*/
privatefunction_init(array$arr)
{
foreach($arras$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]instanceofTree //父级为Tree对象
){
self::$_indexs[$parent_id]->addChild($item);
}elseif($count_paths==1){
$this->addChild($item);
}else{
thrownewException("path数据错误".var_export($item,true));
}
}
//print_r(self::$_indexs);
}
/**
*添加子节点
*
*@paramarray$item
*@returnvoid
*/
publicfunctionaddChild(array$item,$parent=NULL)
{
$child =newTree();
$child->_info =$item;
$child->_parent=$parent==NULL?$this:$parent;
$child->_parent->_child[]= $child;
$this->_addIndex($item,$child->_getSelf());
}
/**
*添加节点到索引
*
*@paramarray$item
*@parammix$value
*@returnvoid
*/
privatefunction_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{
thrownewException("id字段不存在或者不为字符串");
}
}
/**
*获取对自己的引用
*
*@returnTreeobjectquote
*/
privatefunction_getSelf()
{
return$this;
}
/**
*获取指定id的节点的子节点
*
*@paramint$id
*@returnTreeobject
*/
publicfunctiongetChild($id)
{
$data =self::$_indexs[$id]->_child;
$this->_data=$data;
return$this;
}
/**
*获取指定id的节点的父节点
*
*@paramint$id
*@returnTreeobject
*/
publicfunctiongetParent($id)
{
$data=self::$_indexs[$id]->_parent;
$this->_data=$data;
return$this;
}
/**
*获取指定id的节点的同级节点
*
*@paramint$id
*@returnTreeobject
*/
publicfunctiongetBrother($id)
{
$data=self::$_indexs[$id]->_parent->_child;
$this->_data=$data;
return$this;
}
/**
*将Tree对象转化为数组
*
*@param object$object
*@returnarray
*/
publicfunctiontoArray($obj=NULL)
{
$obj =($obj===NULL)?$this->_data:$obj;
$arr =array();
$_arr=is_object($obj)?$this->_getBaseInfo($obj):$obj;
if(is_array($_arr)){
foreach($_arras$key=>$val){
$val=(is_array($val)||is_object($val))?$this->toArray($val):$val;
$arr[$key]=$val;
}
}else{
thrownewException("_arr不是数组");
}
return$arr;
}
/**
*过滤_parent等字段,以免造成无限循环
*
*@paramobject$obj
*@returnvoid
*/
privatefunction_getBaseInfo($obj)
{
$vars=get_object_vars($obj);
$baseInfo['_info'] = $vars['_info'];
$baseInfo['_child']= $vars['_child'];
return$baseInfo;
}
/**
*二维数组排序
*
*根据指定的键名对二维数组进行升序或者降序排列
*
*@paramarray $arr二维数组
*@paramstring$keys
*@paramstring$type必须为asc或desc
*@throws当参数非法时抛出异常
*@return返回排序好的数组
*/
privatefunction_array_sort(array$arr,$keys,$type='asc'){
if(!is_string($keys)){
thrownewException("非法参数keys:参数keys的类型必须为字符串");
}
$keysvalue=$new_array=array();
foreach($arras$k=>$v){
if(!is_array($v)||!isset($v[$keys])){
thrownewException("参数arr不是二维数组或arr子元素中不存在键'{$keys}'");
}
$keysvalue[$k]=$v[$keys];
}
switch($type){
case'asc':
asort($keysvalue);
break;
case'desc':
arsort($keysvalue);
break;
default:
thrownewException("非法参数type:参数type的值必须为'asc'或'desc'");
}
reset($keysvalue);
foreach($keysvalueas$k=>$v){
$new_array[$k]=$arr[$k];
}
return$new_array;
}
}
?>
希望本文所述对大家的PHP程序设计有所帮助。