本帖最后由 xuzuning 于 2010-08-12 07:04:00 编辑

解决方案 »

  1.   

    是不是要求写一个send函数啊?
      

  2.   

    send函数内部应该是用类似
    $pattern = array("{headline}", "{drill}");
    $replacement = tree();
    $output = str_replace($pattern, $replacement, $tpl);
      

  3.   

    我先写个递归的抛砖引玉。。function send($tree){
        global $tpl;
        if (isset($tree['bz'])){
            $drill = empty($tree['child']) ? '' : send($tree['child']);
            return str_replace(array('block=tree,0,1','{bz}','{handline}','{drill}'),array('',$tree['bz'],$tree['handline'],$drill),$tpl);
        } else {
            foreach ((array)$tree as  $key => $node){
                $rs.= send($node);
            }
        }
        return $rs;
    }
    echo send(tree());
      

  4.   


    echo send(array('action'=>'run', 'data'=>$tpl));function send($senddata){
    $ar = $senddata['action']=="run"?tree():$senddata['action'];
    $str="";
    foreach($ar as $ar_v){
    $drill = (isset($ar_v['child']) && is_array($ar_v['child']))?send(array('action'=>$ar_v['child'], 'data'=>$senddata['data'])):"";
    $str .= preg_replace('~(.*?)\{bz\}(.*?)\{handline\}(.*?)\{drill\}(.*?)~is',"\\1{$ar_v['bz']}\\2{$ar_v['handline']}\\3{$drill}\\4",$senddata['data']);
    }
    return $str;
    }跟一个
      

  5.   

    呵呵,还是有人感兴趣
    这是另一个版本<?php
    /**
     * 本程序由代码生成器TBuilder根据模板生成
     * 使用PHP版本 5.2.6
     * 生成时间2010-08-11 10:23:44
     * 耗用时间 2,553 微秒
     * 请根据实际需要保存和修改代码
     **/include_once 'lib/TApplication.php';
    class Application extends TApplication {
      function init() {
    /*
     * 在这里书写类实例化以后,执行run方法之前
     * 需要执行的代码
     **/
      }
      /**
       * 用户方法 tree
       * 功能 向模板提供数据
       * 参数
       *  $row 未用
       *  $col 未用
       * 
       *   当$col<2时,$row一般用于控制输出的行数
       *   当$col>1时,可用$row*$col控制输出的数据总量
       *   见TTemplate类说明
       * 
       **/
      function tree($row=0, $col=1) {
    /**
     * 模板需要本方法返回如下结构的数组
     **/
    $ar = array(
    array(
    'bz' => '-',
    'handline' => 'A',
    'child' => array(
    array(
    'bz' => '-',
    'handline' => 'AA',
    'child' => array(
    array(
    'bz' => '.',
    'handline' => 'AAA',
    ),
    ),
    ),
    ),
    ),
    array(
    'bz' => '-',
    'handline' => 'B',
    'child' => array(
    array(
    'bz' => '-',
    'handline' => 'BB',
    'child' => array(
    array(
    'bz' => '.',
    'handline' => 'BBB',
    ),
    ),
    ),
    ),
    ),
    );
    /**
     * 钻探方式(drill)所需要的树状数组可通过类TTree由二维数组取得
     * include_once 'lib/TTree.php';
     * $t = new TTree;
     * $ar = $t->parse($array, true);
     * 详情请见TTree类说明
     *  也可以用
     *  Array = send(array(
     *   'action' => 'tree',
     *   'data' => $array,
     *   'type' => true,
     *   ));
     *  取得,详情见信号说明
     **/ return $ar;
      }
    }$tpl =<<< TPL
    <table block=tree,0,1>
    <tr><td>{bz}</td><td>{handline}</td></tr>
    <tr><td></td><td>{drill}</td></tr>
    </table>
    TPL;$app = new Application;
    $app->run($tpl);
    ?>
      

  6.   

    核心就一个递归函数,,,偷懒,替换不够干净,所以就不用send函数名了我觉得从数据库中拿出数据,整理成树数组,要比现在这一步复杂吧,不过都算是基本功function makeTree($arr, $tpl)
    {
    $str = '';
    foreach($arr AS $val)
    {
    $str .= $tpl;
    foreach($val AS $k => $v)
    {
    if(!is_array($v))
    {
    $str = str_replace('{' . $k . '}', $v, $str);
    }
    else
    {
    $str = str_replace('{drill}', makeTree($v, $tpl), $str);
    }
    }
    $str = str_replace('{drill}', '', $str);
    }
    return $str;
    }
      

  7.   

    拿去用吧,根楼主要求的数据一模一样,呵呵。确实有点绕人。
    另外,楼主的模板内的 table里block是不需要的,不明白要那个有什么有,有问题再留言:function send($par)
    {
    if ($par['action'] == 'run')
    {
    static $arr;
    $arr = $arr?$arr:tree();
    $tmp = $arr;
    $ret = '';
    foreach((array)$tmp as $key=>$data){
    //var_dump($data);
    $tpl=$par['data'];
    foreach((array)$data as $k=>$v){
    if ($k=='child'){
    $arr = $v;
    $tpl = str_replace('{drill}',send(array('action'=>'run', 'data'=>$par['data'])),$tpl);
    }else{
    $tpl = str_replace('{'.$k.'}',$v,$tpl);
    }
    }
    $tpl = str_replace('{drill}','',$tpl);
    $ret = $ret.$tpl;
    }
    return $ret;
    }
    }
      

  8.   

    up下,生成树数组的过程可能要比这复杂的多一个递归函数就行了,或者遍历数组也可以
    当年用了三种方式仿csdn写的树:纯js,ajax和纯php
    http://www.zzxj.net/forum/
      

  9.   

    其实我觉得楼主的这个问题本身并不难,只是他的参数内没有接收子的tree()数组,所有要用到一个静态变量去控制子节点的数据源。
    我看楼上很多回复都没有考虑到这点,传统意义上的递规都是将数据一层一层传递下去的,而这个接口的参数里根本没有数据数据参数。
      

  10.   

    楼上的说的太片面了吧方法没有写接收的参数难道就不可以传参?
    又不是非得用静态的才能做.
    用传统的递归就能达到(我们可以吧数据源与模板做到同一个数组里传,func_get_args也可以取)
      

  11.   

    谢谢大家的参与!
    开始发帖时把问题弄简单了,现在重新发问题
    $tpl =<<< TPL
    <body block=body>
    <p>{headline}</p>
    <table block=tree,0,1>
    <tr><td>{bz}</td><td>{handline}</td></tr>
    <tr><td></td><td>{drill}</td></tr>
    </table>
    TPL;
    function body() {
      return array('headline' => '这是一个测试');
    }
    function tree($row=0, $col=1) {
      $ar = array(
    array( 'bz' => '+', 'handline' => 'A', 'id' => 1, 'pid' => 0),
    array( 'bz' => '+', 'handline' => 'AA', 'id' => 2, 'pid' => 1),
    array( 'bz' => '.', 'handline' => 'AAA', 'id' => 3, 'pid' => 2),
    array( 'bz' => '+', 'handline' => 'B', 'id' => 4, 'pid' => 0),
    array( 'bz' => '+', 'handline' => 'BB', 'id' => 5, 'pid' => 4),
    array( 'bz' => '.', 'handline' => 'BBB', 'id' => 6, 'pid' => 5),
    );
      return send(array('action' => 'tree', 'data' => $ar, 'type' => true));
    }echo send(array('action'=>'run', 'data'=>$tpl));生成的html代码<body>
    <p>这是一个测试</p>
    <table>
    <tr><td>+</td><td>A</td></tr>
    <tr><td></td><td><table>
    <tr><td>+</td><td>AA</td></tr>
    <tr><td></td><td><table>
    <tr><td>.</td><td>AAA</td></tr>
    <tr><td></td><td></td></tr>
    </table></td></tr>
    </table></td></tr>
    </table><table>
    <tr><td>+</td><td>B</td></tr>
    <tr><td></td><td><table>
    <tr><td>+</td><td>BB</td></tr>
    <tr><td></td><td><table>
    <tr><td>.</td><td>BBB</td></tr>
    <tr><td></td><td></td></tr>
    </table></td></tr>
    </table></td></tr>
    </table></body>问题的核心不是如何编写那棵树的代码。而是实现这种程序写法的可能途径
    因为没有工具的支撑,楼上几位的代码虽然精巧但并无多大实际意义。当然还是很感谢的欢迎继续讨论!
      

  12.   

    这个就和js dtree一样了,连数据结构都一样。
    只是一个JS,一个PHP。
      

  13.   

    本帖最后由 xuzuning 于 2010-08-11 15:43:03 编辑
      

  14.   

    另外
    当把 模板中的 <table block=tree,0,1>
    改为 <table block=tree>
    后,输出的html就变成<body>
    <p>这是一个测试</p>
    <table><tr><td>+</td><td>A</td></tr>
    <tr><td></td><td><tr><td>+</td><td>AA</td></tr>
    <tr><td></td><td><tr><td>.</td><td>AAA</td></tr>
    <tr><td></td><td></td></tr>
    </td></tr>
    </td></tr>
    <tr><td>+</td><td>B</td></tr>
    <tr><td></td><td><tr><td>+</td><td>BB</td></tr>
    <tr><td></td><td><tr><td>.</td><td>BBB</td></tr>
    <tr><td></td><td></td></tr>
    </td></tr>
    </td></tr>
    </table></body> 19楼 sdomain 朋友很仔细:“模板内的 table里block是不需要的,不明白要那个有什么用”
    真的没有用吗?认真想一想
      

  15.   

    一种可能我们只是在php递归生成好一个一个的table在页面初始化的时候使用js利用id,pid构造这棵树
      

  16.   

    有点像我以前写的那个,不过我的tpl只对应每个节点的html而不是在里面再包含子集合的tpl({drill}),所以每个节点前缀的生成成了唯一需要编码的地方,因为我觉得树的ui,div或者ul/li就够了,table好像没什么必要。我的树形数据也没有组织得这么麻烦,php数组的hash特性其实方便很多,我习惯将树形数组转成二维数组,$array[父id] -> 子集合 , 太深层的数组不好调试。。 
      

  17.   

    <?php
    $arr = array(
    "A" => array(
    "AA" => array("AAA")
    ),

    "B" => array(
    "BB" => array("BBB")
    )
    );

    foreach($arr as $k=>$v){
    echo $k."<br/>"; if($k == "A"){
    foreach($v as $k1=>$v1){
    echo "<br/>&nbsp".$k1."<br/>";
    }
    }else if($k == "B"){
    foreach($v as $k1=>$v1){
    echo "<br/>&nbsp".$k1."<br/>";
    }
    }
    }
    ?>
      

  18.   

    http://www.zzxj.net/forum/不错哇~~~~
      

  19.   

    老大,看我这个符不符你要求,通过给分啊递归实现,测试通过$tpl =<<< TPL
    <table block=tree,0,1>
    <tr><td>{bz}</td><td>{handline}</td></tr>
    <tr><td></td><td>{drill}</td></tr>
    </table>
    TPL;function tree() {
      $ar = array(
        array(
            'bz' => '-',
            'handline' => 'A',
            'child' => array(
                array(
                    'bz' => '-',
                    'handline' => 'AA',
                    'child' => array(
                        array(
                            'bz' => '.',
                            'handline' => 'AAA',
                            ),
                        ),
                    ),
                ),
            ),
        array(
            'bz' => '-',
            'handline' => 'B',
            'child' => array(
                array(
                    'bz' => '-',
                    'handline' => 'BB',
                    'child' => array(
                        array(
                            'bz' => '.',
                            'handline' => 'BBB',
                            ),
                        ),
                    ),
                ),
            ),
        );
        return $ar;
    }
    //fxs_2008's code
    $d=tree();
    $t=$tpl;function maketree($d,$t){
    $str='';
         foreach($d as $v){
            if(isset($v['child'])){
    $str .=str_replace(array('{bz}','{handline}','{drill}'),array($v['bz'],$v['handline'],maketree($v['child'],$t)),$t);
    }else{
          $str .= str_replace(array('{bz}','{handline}','{drill}'),array($v['bz'],$v['handline'],''),$t);
    }
     }
     return $str;
    }echo '<pre>';
    print_r(maketree($d,$t));
    echo '</pre>';
      

  20.   


    多谢,那个是和CSDN一样的无限分类树
      

  21.   

    呵呵,再写一个,把数组  递归成 需要的数组结构
      $ar = array(
        array( 'bz' => '+', 'handline' => 'A', 'id' => 1, 'pid' => 0),
        array( 'bz' => '+', 'handline' => 'AA', 'id' => 2, 'pid' => 1),
        array( 'bz' => '.', 'handline' => 'AAA', 'id' => 3, 'pid' => 2),
        array( 'bz' => '+', 'handline' => 'B', 'id' => 4, 'pid' => 0),
        array( 'bz' => '+', 'handline' => 'BB', 'id' => 5, 'pid' => 4),
        array( 'bz' => '.', 'handline' => 'BBB', 'id' => 6, 'pid' => 5),
        );
    $Tree = makeTreeArray($ar, 0);
    print_r($Tree);//打印
    function makeTreeArray($arr, $pid = 0)
    {
    $chindrens = array();
    foreach($arr AS $k => $v)
    {
    if($v['pid'] == $pid)
    {
    unset($arr[$k]);
    if($child = makeTreeArray($arr, $v['id']))
    {
    $v['child'] = $child;
    }
    $chindrens[] = $v;
    }
    }
    return $chindrens;
    }
      

  22.   

    是不是讨论那个工具是如何自动生成PHP程序的吗?这个要告诉大家程序做了哪些工作,最后生成的是什么样的东西-或者说参数和结果
      

  23.   

    本帖最后由 xuzuning 于 2010-08-12 13:52:38 编辑
      

  24.   

    这代码有点多了,php写的代码就这么难看。
    路过,注释都不多写点。