树类
tree_class.inc.php
<?
class Tree {
  var $data = array();
  var $tpl = '<table cellpadding=0 cellspacing=0 border=0 style="font-size:9pt">$块</table>';
  var $block = '<tr onClick="tree_onclick()" bs=$标识><td>$主图标</td><td>$副图标 $文字</td></tr><tr style="display:$可见"><td background="$连线"></td><td value="$编号">$子树</td></tr>';  var $images = array( // 节点图片
array("images/tree_L.gif","images/tree_T.gif","images/icon-page.gif"),
array("images/OpenFolder_L.gif","images/OpenFolder_T.gif","images/FolderClose.gif","images/FolderOpen.gif"),
array("images/CloseFolder_L.gif","images/CloseFolder_T.gif","images/FolderClose.gif","images/FolderOpen.gif"),
array("none","images/tree_I.gif"),
);  var $bond = array("","数据加载中...");
  var $all = false; // 是否产生一棵子树
  var $child_node_pos = 1; // 指示子节点出现的位置
  var $js_display;  /**
   * Tree 构造函数
   */
  function Tree() {
  }
  /**
   * table 方法
   * 功能 产生以表格方式组织的数据
   * 说明 主要用于调试
   */
  function table($format="",$head="") {
if(count($this->data) <= 0) return $this->out = "";
$out = "<table $format><tr>";
if($head == "") {
foreach($this->data as $v) break;
$head = array_keys($v);
}
foreach($head as $v)
$out .= "<th>$v</th>";
$out .= "</tr>";
foreach($this->data as $value) {
$out .= "<tr>";
foreach($head as $k)
$out .= "<td>$value[$k]</td>";
$out .= "</tr>";
}
return $this->out = "$out</table>";
  }
  /**
   * node_all 方法
   * 功能 根据模板构造全部数据
   */
  function node_all($id, $key=array("id","pid","text","link")) {
$this->all = true;
return $this->node($id,$key);
  }
  /**
   * index 方法
   * 功能 索引树
   */
  function index($start=0, $key=array("id","pid")) {
$fun = create_function('$a,$b'
,"if(\$a[$key[1]] == \$b[$key[1]]) return 0;"
."return \$a[$key[1]] > \$b[$key[1]]?1:-1;");
$out = array();
foreach($this->data as $k=>$v) {
if($v[$key[1]] == $start)
$out[] = $v;
else
$this->insert($v,&$out,$key);
}
return $this->data = $out;
  }
  /**
   * insert 方法
   * 功能 插入节点
   */
  function insert($value,$array="",$key=array("id","pid")) {
if($array == "") $array =& $this->data;
if(count($array) <= 0) {
$array[] = $value;
return true;
}
$k = $m = $n = 0;
$ar = array();
foreach($array as $t) {
$k++;
if($t[$key[0]] == $value[$key[1]]) $m = $k;
if($t[$key[1]] == $value[$key[1]] || in_array($t[$key[1]],$ar)) {
$n = $k;
$ar[] = $t[$key[0]];
}
}
$k = max($m,$n);
if($k == 0) return false;
$array = array_merge(array_slice($array,0,$k),array($value),array_slice($array,$k));
$this->build($key);
return true;
  }
  /**
   * update 方法
   * 功能 修改节点
   */
  function update() {
  }
  /**
   * delete 方法
   * 功能 删除节点
   */
  function delete() {
  }
  /**
   * move 方法
   * 功能 移动节点
   */
  function move() {
  }
  /**
   * display 方法
   * 功能 显示
   */
  function display($type="node_all",$key=array("id","pid","text","link")) {
switch($type) {
case "table":
$this->table();
break;
case "node_all":
$this->out = $this->node_all(0,$key);
break;
}
echo $this->out;
$this->javascript();
  }
  function javascript() {
static $key;
if(! empty($key)) return;
echo <<< JS
<script>
function tree_onclick() {
  el = event.srcElement;
  switch(event.srcElement.tagName) {
case "A":
case "IMG":
while(el.tagName != "TR") el = el.parentElement;
break;
default:
return;
  }
  if(el.bs == 0) return; // bs=0 表示是叶节点; =1 为L接; >1 为T接
  var pos = el.rowIndex;
  var el1 = el.parentElement.rows[pos+1];
  if(el1.style.display == "block") {
el1.style.display = "none";
el.cells[0].children[0].src = (el.bs==1?images[0][0]:images[0][1]);
if(el.cells[1]) if(el.cells[1].children[0]) el.cells[1].children[0].src = images[1][2];
  }else {
el1.style.display = "block";
el.cells[0].children[0].src = (el.bs==1?images[1][0]:images[1][1]);
if(el.cells[1]) if(el.cells[1].children[0]) el.cells[1].children[0].src = images[1][3];
  }
  el = el1.cells[{$this->child_node_pos}];
  if(el.innerHTML == bond) Tree_load.src = "?node="+el.value;
}
myload = 0;
function tree_load_end() { if(myload != 0) el.innerHTML = myload; }
</script>
<script id='Tree_load' src='' onreadystatechange='tree_load_end()'></script>
JS;
$js = "<script>\n";
$js .= "images = new Array(\nnew Array(";
foreach($this->images[1] as $v) $js .= "'$v',";
$js = substr($js,0,-1)."),\n";
$js .= "new Array(";
foreach($this->images[2] as $v) $js .= "'$v',";
$js = substr($js,0,-1).")\n);\n";
$js .= "bond = '{$this->bond[1]}';";
$js .= "</script>";
echo $js;
$key = 1;
  }
  function find($id,$key=array("id","pid")) {
foreach($this->data as $v)
if($v[$key[1]] == $id) return true;
return false;
  }
  /**
   * filter方法
   * 功能 返回$id的一级子集
   */
  function filter($id,$key=array("id","pid")) {
$cmd = create_function('$var',"return(\$var[$key[1]]=='$id');");
return array_filter($this->data,$cmd);
  }
  /**
   * node 方法
   * 功能 根据模板构造指定节点数据
   */
  function node($id,$key=array("id","pid","text","link")) {
$ar = $this->filter($id,$key);
if(($n = count($ar)) == 0) return "";
$块 = "";
foreach($ar as $value) {
$n--;
$p = sign($value[node_childs]);
$可见 = "none";//"block";
$标识 = $p==0 ? $p : $p+$n;
$主图标 = "<img src=\"{$this->images[$p][sign($n)]}\" align=absmiddle>";
$副图标 = empty($this->images[$p][2]) ? "" : "<img src=\"{$this->images[$p][2]}\" align=absmiddle>";
$文字 = empty($value[$key[3]]) ? $value[$key[2]] : "<a href=\"{$value[$key[3]]}\">{$value[$key[2]]}</a>";
$连线 = $this->images[3][sign($n)]; $编号 = $value[id];
$子树 = $this->all ? $this->node($value[$key[0]],$key) : $this->bond[$p];
$块 .= eval("return \"".AddSlashes($this->block)."\";");
}
return eval("return \"\n".AddSlashes($this->tpl)."\";");
  }
  /**
   * build方法
   * 功能 计算各节点的一级子节点数,用附加的node_childs表示
   */
  function build($key=array("id","pid")) {
foreach($this->data as $k=>$v) {
$this->data[$k][node_childs] = count($this->filter($v[$key[0]]));
}
  }
}
?>测试1——直接生成树的全部节点
<?
include "tree_class.inc.php";
$t = new tree;$conn = mysql_connect();
mysql_select_db("test");
$sql = "select * from menu"; 
$rs = mysql_query($sql);while($row = mysql_fetch_row($rs)) {
  $t->insert(array(id=>$row[0], pid=>$row[2], text=>$row[1]));
}$t->display();
?>测试2——动态生成树的子节点
<?
include "tree_class.inc.php";
$t = new tree;$conn = mysql_connect();
mysql_select_db("test");
$sql = "select * from menu"; 
$rs = mysql_query($sql);while($row = mysql_fetch_row($rs)) {
  $t->insert(array(id=>$row[0], pid=>$row[2], text=>$row[1]));
}if(! isset($_GET['node'])) {
  $t->javascript();
  echo $t->node(0);
}else { // 分步加载时返回指定节点
  $s = $t->node($_GET['node']);
  $s = preg_replace("/\r?\n/","\\n",$s);
  echo "myload = '$s'";
}
?>数据
id name pid 
1 aaa 0 
2 bbb 0 
3 ccc 0 
4 a1 1 
5 a2 1 
6 b1 2 
7 xxx 6 

解决方案 »

  1.   

    节点图片
    <?php
    $images = array(
    array('images/tree_I.gif','R0lGODlhEwAUAIAAAHt7e////yH5BAUUAAEALAAAAAATABQAAAIbjG+Ay+2tnpws0ist3kvz731bKF5kOZ3oo6IFADs='),
    array('images/tree_L.gif','R0lGODlhEwAUAIAAAHt7e////yH5BAUUAAEALAAAAAATABQAAAIbjG+Ay+2tnpws0ist3kvzr4SB6H3miabqyhoFADs='),
    array('images/tree_T.gif','R0lGODlhEwAUAIAAAHt7e////yH5BAUUAAEALAAAAAATABQAAAIdjG+Ay+2tnpws0ist3kv58GkcNJaJWYoopa6Z2xQAOw=='),
    array('images/OpenFolder.gif','R0lGODlhEgASAJEAAP///29vbwAAAP///yH5BAUUAAMALAAAAAASABIAAAIunI+py+0mopxiCYBzrupqzSUeNgIhUqYWOZHB8B4puG50991ivlkU9QgKh8RHAQA7'),
    array('images/OpenFolder_L.gif','R0lGODlhEgASAPcAAAAAAP///21tbQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAMALAAAAAASABIAAAhPAAcIHChQAMGDCBMqPGhwocB/ECNK/JfwX4CLGDFSRGgxY8aNBzteFBkAJEGSKCuOlDjSYMOHHz+q1CiTo8eaIW9qrDhxosOfQIMKHTogIAA7'),
    array('images/OpenFolder_T.gif','R0lGODlhEgASAJEAAAAAAP///21tbf///yH5BAEAAAMALAAAAAASABIAAAIynG+Cy+2rngG0WtBA2JxjpnXdt4SbGZAIymandSrRNI6uZ4NiXu5edrlIEsNicWYcFgAAOw=='),
    array('images/CloseFolder.gif','R0lGODlhEgASAJEAAP///29vbwAAAP///yH5BAUUAAMALAAAAAASABIAAAIvnI+py+0mopxiCYBzrupqzSXeh4XISJqHR5XB8K7kZs1lbauQDegDBXwIh8TiowAAOw=='),
    array('images/CloseFolder_L.gif','R0lGODlhEgASAJEAAP///29vbwAAAP///yH5BAUUAAMALAAAAAASABIAAAIwnG+By+2rnhG0WtEE2JxjpnXdt4TiRiLmmR7hhSrRdHpZjd54S+/ZdZEIh8SicVAAADs='),
    array('images/CloseFolder_T.gif','R0lGODlhEgASAJEAAP///29vbwAAAP///yH5BAUUAAMALAAAAAASABIAAAIxnG+By+2rnhG0WtEE2JxjpnXdt4TiRiLmmR7hhSrRdHpZjd54S+/ZdZEkhETirCgsAAA7'),
    array('images/FolderClose.gif','R0lGODlhEgASALMAAP//Mf/zKf/vKf/rKf/nKf/jKf/fKf/bKf/XIf/PIf/HIf+qIca6MQAAAP///wAAACH5BAUUAA4ALAAAAAASABIAAARb0MlJq714sr1blgwgioyHcWjKLBQTvEM8FPSBLKbjBvJcI7ccQ0AkGA1IYFDToxVswASOGXNCEQmp0EhAGpRZreaYjGYVU5AVfEYLF/C4PJ5zNO74fP7D7/s/EQA7'),
    array('images/FolderOpen.gif','R0lGODlhEgASAMQAAP/3Kf/zKf/vKf/rKf/nKf/jKf/fKf/bKf/XKf/TIf/PIf/LIf/HIf+qIca6MQAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAUUABAALAAAAAASABIAAAVfICSOZGmeKOmsazo6QBw7LizLLKvePP68vZ7jB8kZc4ChqBFoDp6FwuEwXBGZgecgOk1UlUst95BILBoP9KhBaBsMiPJiMVSvx/K5A01cNv6AgXwlD4WGh4YuiouMKSEAOw=='),
    array('images/icon-expandall.gif','R0lGODlhEAAPAIAAAAAAAAAAACH5BAEAAAEALAAAAAAQAA8AQAIXjI+pBosAY3S02iOby/L6DzKcNYXmeRQAOw=='),
    array('images/icon-closeall.gif','R0lGODlhEAAPAIAAAAAAAAAAACH5BAEAAAEALAAAAAAQAA8AQAIXjI+pwKzXonu0WgqujLf7D1aNtoUmUgAAOw=='),
    array('images/icon-page.gif','R0lGODlhEAAQAKIEAP///wAAAH9/f8jIyP///wAAAAAAAAAAACH5BAEAAAQALAAAAAAQABAAAAM9SBSh/jCAIKqtbTEwueeZ9Imjwohk6UjsiT7bpzoC2IJQLXsZbZ+4h243ye0sPcXQMygaZYPkynWCWK+OBAA7')
    );
    if(! isset($_GET['id'])) {
      echo "<table border>";
      foreach($images as $k=>$v)
        echo "<tr><td>$v[0]</td><td><img src='?id=$k'></td></tr>";
      echo "</td></tr></table>";
    }else {
      echo base64_decode($images[$_GET['id']][1]); 
      if(0) // 1 写入文件,请保证目录存在且可写
      foreach($images as $v) {
        $fp = fopen($v[0],"wb");
        fwrite($fp,base64_decode($v[1]));
        fclose($fp);
      }
    }
    ?>
      

  2.   

    那是图片文件的base64编码,不要去改他。如果你没有合适的图片,可以通过2楼的程序获得。
      

  3.   

    echo <<< JS
    干嘛用的?
      

  4.   

    好象用javascript也可以实现的哦.