首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > PHP >

晒一上小弟我的模板引擎,欢迎拍砖

2013-01-25 
晒一下我的模板引擎,欢迎拍砖本帖最后由 xuzuning 于 2012-05-23 15:02:49 编辑别不多说,直接上代码templa

晒一下我的模板引擎,欢迎拍砖
本帖最后由 xuzuning 于 2012-05-23 15:02:49 编辑 别不多说,直接上代码
template.php(3.55K)

<?php
class template {
  protected $data = array();
  protected $drillmode = 0;
  function __construct($s) {
if(file_exists($s)) $s = file_get_contents($s);
$this->find_var($s);
$this->data = explode('<', $s);
$this->data[0] = '<?php $_st=$_var=array();?>';
$this->find_dsn();
  }
  //新增 run 方法,
  function run() {
//include "data://," . join('<', $this->data);
eval('?>' . join('<', $this->data));
  }
  function find($pattern) {
$this->pattern = $pattern;
return array_filter($this->data, array($this, 'find_callback'));
  }
  private function find_dsn() {
foreach($this->find("#\bdsn\b#i") as $k=>$v) {
$t = $this->find_tag($tag = strtok($v, ' '), $k);
end($t);
$dsn[] = array( $k, key($t) );
}
if($this->drillmode) {
foreach($this->find("#\bdrill\b#i") as $k=>$t) {
foreach($dsn as $i=>$v) if($k < $v[1] && $k > $v[0]) $t = $i;
$drill[] = $dsn[$t];
unset($dsn[$t]);
}
}
foreach($dsn as $v) {
list($start, $end) = $v;
preg_match('/\bdsn\s*=\s*([^\s>]+)/i', $this->data[$start], $reg);
$this->data[$start] = str_replace(' '.$reg[0], '', $this->data[$start]);

$m = explode(',', trim($reg[1], '\'"')) + array(0, 0, '');
$code_start = "?php if(isset(\$_var))\$_st[]=\$_var;foreach((isset(\$_var['$m[0]'])?\$_var['$m[0]']:\$this->$m[0]('$m[1]','$m[2]')) as \$_key=>\$_var){?>";
$code_end = "?php }\$_var=array_pop(\$_st);?>";
switch($m[1]) {
case 0:
$t = explode('>', $this->data[$start]);
$t[1] = "<$code_start" . $t[1];
$this->data[$start] = join('>', $t);
$this->data[$end] = "$code_end<" . $this->data[$end];
break;
case 1:
$this->data[$end] .= "<$code_end";
$this->data[$start] = "$code_start<" . $this->data[$start];
break;
default:
$n = round(100/$m[1]);
$this->data[$end] .= "</dt><$code_end";
$this->data[$start] = "$code_start<dt style='float:left;width:$n%;margin:0px;padding:0px'><" . $this->data[$start];
break;
}
}
if($this->drillmode) foreach($drill as $v) {
list($start, $end) = $v;
preg_match('/\bdsn\s*=\s*([^\s>]+)/i', $this->data[$start], $reg);
$this->data[$start] = str_replace(' '.$reg[0], '', $this->data[$start]);
$m = explode(',', trim($reg[1], '\'"')) + array(0, 0, '');
$code = '';
for($i=$start; $i<=$end; $i++) {
$code .= '<' . $this->data[$i];
if($i > $start) unset($this->data[$i]);
}
$code = addslashes($code);


$this->data[$start] = "?php \$_code='$code';\$this->drill(\$_code, isset(\$_var['$m[0]'])?\$_var['$m[0]']:\$this->$m[0]('$m[1]','$m[2]'));?>";
}
  }
  protected function find_tag($tag, $offs=0) {
$r = array();
$counter = 0;
foreach($this->find("#^/?$tag#i") as $k=>$v) {
if($k >= $offs) {
$counter += $v{0} == '/' ? 1 : -1;
$r[$k] = $v;
if($counter == 0) break;
}
}
return $r;
  }
  protected function find_callback($v) {
return preg_match($this->pattern, $v);
  }
  private function find_var(&$s) {
$s = preg_replace_callback('/\{(\w+)\}/', array($this, 'var_callback'), $s);
  }
  protected function var_callback($r) {
if($r[1] == 'drill') {
$this->drillmode++;
return '<?php if(isset($_var[\'child\'])) $this->drill($_code, $_var[\'child\']);?>';
}
return "<?php echo isset(\$_var['$r[1]'])?\$_var['$r[1]']:'';?>";
  }
  protected function drill($_code, $_source) {
  if(empty($_source) || ! is_array($_source)) return array();
  foreach($_source as $_key=>$_var) {
//include 'data://,' . $_code;
eval('?>' . $_code);
  }
  }
  function __call($func, $param) {
if(function_exists($func)) return call_user_func_array($func, $param);
return array();
  }
  function __toString() {
return join('<', $this->data);
  }
}



补充一下
模板中只有两种控制元素:
1、模板变量 用花括号括起的变量名,如 {var}。提供数据的函数应提供对应的数据,如没有提供则自动为空
2、数据源声明 位于 HTML 标记中的 dsn 属性,比如 
<p dsn='foo,1'>{t}</p>
其中 foo 表示提供数据的函数,1 表示充填数据时,循环是包含自身的 比如返回的数据是 array(array('t'=>1,array('t'=>2))
则实际生成的 html 是 <p>1</p><p>2</p>
当第二个参数缺省时,同样的数据只产生 <p>12</p>
3、数据源函数约定返回的是二维数组:第一维是下标数组,第二维是关联数组。请参见测试例

写程序很简单,写文档就要了我的命了

相关问题解答见 #39

一个扩展的用法见 #61
[解决办法]
Fatal error: Call to undefined function find_child() in E:\test.local\test.php on line 51
出现了这个错误。是怎么回事啊?
[解决办法]
不理解了:


Warning: include() [function.include]: data:// wrapper is disabled in the server configuration by allow_url_include=0 in \path\template_csdn\template_class.php on line 13

Warning: include(data://,<?php $_st=$_var=array();?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><?php if(isset($_var))$_st[]=$_var;foreach((isset($_var['body'])?$_var['body']:$this->body('0','')) as $_key=>$_var){?> <head> <meta name="generator" content="HTML Tidy, see www.w3.org" /> <meta http-equiv="Content-Type" content= "text/html; charset=gb2312" /> <title><?php echo isset($_var['title'])?$_var['title']:'';?></title> <style type="text/css"> /*&raquo;&ugrave;&plusmn;&frac34;&ETH;&Aring;&Iuml;&cent;*/ body {font:12px Tahoma;margin:0px;text-align:center;background:#FFF;} a:link,a:visited {font-size:12px;text-decoration:none;} a:hover{} #side { background: #99FF99; height: 100%; width: 200px; float: left; } in \path\template_csdn\template_class.php on line 13



Warning: include() [function.include]: Failed opening 'data://,<?php $_st=$_var=array();?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><?php if(isset($_var))$_st[]=$_var;foreach((isset($_var['body'])?$_var['body']:$this->body('0','')) as $_key=>$_var){?> <head> <meta name="generator" content="HTML Tidy, see www.w3.org" /> <meta http-equiv="Content-Type" content= "text/html; charset=gb2312" /> <title><?php echo isset($_var['title'])?$_var['title']:'';?></title> <style type="text/css"> /*&raquo;&ugrave;&plusmn;&frac34;&ETH;&Aring;&Iuml;&cent;*/ body {font:12px Tahoma;margin:0px;text-align:center;background:#FFF;} a:link,a:visited {font-size:12px;text-decoration:none;} a:hover{} #si in \path\template_csdn\template_class.php on line 13


[解决办法]
问个问题

如何解决<ul><li class=""></li>……    比如是个排名列表,前面3个li class名都不一样,再后面都和第四一致
[解决办法]

<div style='text-align:left'>
<?php $_code='<ul class=TreeView>
 <li ><?php echo isset($_var[''NAME''])?$_var[''NAME'']:'''';?><?php if(isset($_var[''child''])) $this->drill($_code, $_var[''child'']);?></li>
</ul>
';$this->drill($_code, isset($_var['tree'])?$_var['tree']:$this->tree('0',''));?></div>
</div>


$p,看到有这么一块。运行不了了

热点排行