讨论一下,这是如何实现的 本帖最后由 xuzuning 于 2010-08-12 07:04:00 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 是不是要求写一个send函数啊? send函数内部应该是用类似$pattern = array("{headline}", "{drill}");$replacement = tree();$output = str_replace($pattern, $replacement, $tpl); 我先写个递归的抛砖引玉。。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()); 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;}跟一个 呵呵,还是有人感兴趣这是另一个版本<?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);?> 核心就一个递归函数,,,偷懒,替换不够干净,所以就不用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;} 拿去用吧,根楼主要求的数据一模一样,呵呵。确实有点绕人。另外,楼主的模板内的 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; }} up下,生成树数组的过程可能要比这复杂的多一个递归函数就行了,或者遍历数组也可以当年用了三种方式仿csdn写的树:纯js,ajax和纯phphttp://www.zzxj.net/forum/ 其实我觉得楼主的这个问题本身并不难,只是他的参数内没有接收子的tree()数组,所有要用到一个静态变量去控制子节点的数据源。我看楼上很多回复都没有考虑到这点,传统意义上的递规都是将数据一层一层传递下去的,而这个接口的参数里根本没有数据数据参数。 楼上的说的太片面了吧方法没有写接收的参数难道就不可以传参?又不是非得用静态的才能做.用传统的递归就能达到(我们可以吧数据源与模板做到同一个数组里传,func_get_args也可以取) 谢谢大家的参与!开始发帖时把问题弄简单了,现在重新发问题$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>问题的核心不是如何编写那棵树的代码。而是实现这种程序写法的可能途径因为没有工具的支撑,楼上几位的代码虽然精巧但并无多大实际意义。当然还是很感谢的欢迎继续讨论! 这个就和js dtree一样了,连数据结构都一样。只是一个JS,一个PHP。 本帖最后由 xuzuning 于 2010-08-11 15:43:03 编辑 另外当把 模板中的 <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是不需要的,不明白要那个有什么用”真的没有用吗?认真想一想 一种可能我们只是在php递归生成好一个一个的table在页面初始化的时候使用js利用id,pid构造这棵树 有点像我以前写的那个,不过我的tpl只对应每个节点的html而不是在里面再包含子集合的tpl({drill}),所以每个节点前缀的生成成了唯一需要编码的地方,因为我觉得树的ui,div或者ul/li就够了,table好像没什么必要。我的树形数据也没有组织得这么麻烦,php数组的hash特性其实方便很多,我习惯将树形数组转成二维数组,$array[父id] -> 子集合 , 太深层的数组不好调试。。 <?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/> ".$k1."<br/>"; } }else if($k == "B"){ foreach($v as $k1=>$v1){ echo "<br/> ".$k1."<br/>"; } } }?> http://www.zzxj.net/forum/不错哇~~~~ 老大,看我这个符不符你要求,通过给分啊递归实现,测试通过$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>'; 多谢,那个是和CSDN一样的无限分类树 呵呵,再写一个,把数组 递归成 需要的数组结构 $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;} 是不是讨论那个工具是如何自动生成PHP程序的吗?这个要告诉大家程序做了哪些工作,最后生成的是什么样的东西-或者说参数和结果 本帖最后由 xuzuning 于 2010-08-12 13:52:38 编辑 这代码有点多了,php写的代码就这么难看。路过,注释都不多写点。 两份PHP程序代码对比,大家认为其编程水平都怎么样?censor.class.php json文件里的数据能指定更新<更改>吗? 求个正则表达式!!!!!!! 这样能做到防注入? 如何在mysql数据表中 合理存放 博客 标签 的问题 请问唠叨,linux下的主机的话,smartemplate应该在哪里有tmp才行? win2000+iis5+php+mysql+phpMyAdmin安装问题 win98的部分机子,如果加上www.,就不能访问,如果不加www.就可以访问,这是什么原因啊? 绝对高分,我的机子启动不起来了,伙计们帮忙,提示是one or more memonery DIMMS are out of rev. 正则表达式怎么写 PHP +Apache环境配置问题(一下午没配好..无语很) PHP中formValidator验证用户名弹出服务器没有返回数据,求解急
$pattern = array("{headline}", "{drill}");
$replacement = tree();
$output = str_replace($pattern, $replacement, $tpl);
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());
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;
}跟一个
这是另一个版本<?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);
?>
{
$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;
}
另外,楼主的模板内的 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;
}
}
当年用了三种方式仿csdn写的树:纯js,ajax和纯php
http://www.zzxj.net/forum/
我看楼上很多回复都没有考虑到这点,传统意义上的递规都是将数据一层一层传递下去的,而这个接口的参数里根本没有数据数据参数。
又不是非得用静态的才能做.
用传统的递归就能达到(我们可以吧数据源与模板做到同一个数组里传,func_get_args也可以取)
开始发帖时把问题弄简单了,现在重新发问题
$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>问题的核心不是如何编写那棵树的代码。而是实现这种程序写法的可能途径
因为没有工具的支撑,楼上几位的代码虽然精巧但并无多大实际意义。当然还是很感谢的欢迎继续讨论!
只是一个JS,一个PHP。
当把 模板中的 <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是不需要的,不明白要那个有什么用”
真的没有用吗?认真想一想
$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/> ".$k1."<br/>";
}
}else if($k == "B"){
foreach($v as $k1=>$v1){
echo "<br/> ".$k1."<br/>";
}
}
}
?>
<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>';
多谢,那个是和CSDN一样的无限分类树
$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;
}
路过,注释都不多写点。