晒一下我的模板引擎,欢迎拍砖

xuzuning 2012-05-22 02:59:17
加精
别不多说,直接上代码
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
...全文
10308 118 打赏 收藏 转发到动态 举报
写回复
用AI写文章
118 条回复
切换为时间正序
请发表友善的回复…
发表回复
45666544 2014-05-27
  • 打赏
  • 举报
回复
先 先 先... mart
oasisxp 2014-03-12
  • 打赏
  • 举报
回复
膜拜高手,慢慢研究。
深圳phper 2013-10-21
  • 打赏
  • 举报
回复
这个必须mark一下
x4112821987 2013-10-21
  • 打赏
  • 举报
回复
徐祖宁?
丨Barneyx 2013-10-18
  • 打赏
  • 举报
回复
看看,我也试试走,新手飘过。。。
patrickjiang 2013-03-13
  • 打赏
  • 举报
回复


围观高手的对话,我看到的页面是这样的,请问这个页面怎么解读?我应该找些什么资料?
xyplcxsydn 2013-01-21
  • 打赏
  • 举报
回复
支持一下~~~~~~~~~~~~~~~~~~~~
huangyu_945 2013-01-10
  • 打赏
  • 举报
回复
有待研究啊。。。。。
阿城守候 2013-01-03
  • 打赏
  • 举报
回复
引用 28 楼 xjl756425616 的回复:
PHP code ? 1234567891011121314151617 function body() { return array( array( 'title' => '布局', 'advertising' => '一贯喜欢用表格布局,这种 DIV+CSS 方式很让人头疼的', 'menu' => array( ……
讨论下而已.
snipersheep 2012-11-12
  • 打赏
  • 举报
回复
用smarty挺好的。
ws_123456 2012-08-13
  • 打赏
  • 举报
回复
Warning: Invalid argument supplied for foreach() in D:\123\template.php on line 34
foreach($dsn as $v)
proaholic 2012-08-09
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

能不能加点注释啊,猛一看不太明白,仔细一看还不如猛一看
正需要模板,哈哈,太感谢了
[/Quote]
哥们真幽默!!
Brodee 2012-07-20
  • 打赏
  • 举报
回复
新手啊,来点注释吧!!

不喝水的鱼 2012-07-04
  • 打赏
  • 举报
回复
我擦,一段时间没来就落这么多了!
最近研究了phpcms等的模板的解析和tag等的东西
感觉模板引擎和tag搭配是最自由的方式


{qy:ads action="getAd" place="24" rows="3" return="list"}
{loop $list $r}
{php $ads_link[]='http://'.$r['linkurl'];$ads_img[]=$r['text'];$ads_alt[]=$r['adsname'];}
{/loop}
{/qy}

解析后

<?php
$_fetch = true;
if($_fetch){
$ads_tag = load::tag("ads_tag", "ads");
if (method_exists($ads_tag, "getAd")) {
$list = $ads_tag->getAd(array('place'=>'24','rows'=>'3','limit'=>'20',));
}
?>
<?php $n=1;if(is_array($list) || is_object($list)) foreach($list AS $r) { ?>
<?php $ads_link[]='http://'.$r['linkurl'];$ads_img[]=$r['text'];$ads_alt[]=$r['adsname'];?>
<?php $n++;}unset($n); ?>
<?
}
if($_htmlcache){
$_htmlblock = ob_get_clean();
q::setAdsCache($_key,$_htmlblock,$htmlcache);
echo $_htmlblock;
$_htmlcache = false;
$_key = "";
}
?>
tyds715 2012-06-20
  • 打赏
  • 举报
回复
向楼主问个问题. 在模板里 我要显示一个<table>,显示的数据来源是一个模板变量二维数组,要根据里面一个键值大小不同, 每行显示的内容和颜色 都不同, 比如有的行显示 “及格” 有的行显示淡红色, 有的灰色。这样的模板咋写? php另写解析函数,或 模板里有循环。 或.... 向你学习, 写个这样的模板文件代码样例到这里吧(恕我肯定一会功夫看不懂你的代码的,要不, 也藐视了你的辛苦。 很愿意与你交流)
tyds715 2012-06-20
  • 打赏
  • 举报
回复
向楼主文个问题. 在模板里 我要显示一个<table>,显示的数据来源与一个模板变量二维数组,要根据里面一个键值大小不同, 每行显示的内容和颜色 都不同, 比如有的行显示 “及格” 有的行显示淡红色, 有的灰色。这样的模板咋写? php另写解析函数,或 模板里有循环。 或.... 向你学习, 写个这样的模板文件代码样例到这里吧(恕我肯定一会功夫看不懂你的代码的,要不, 也藐视了你的辛苦。 很愿意与你交流)
tsucx 2012-06-17
  • 打赏
  • 举报
回复
做个记号,这个用得到。
总哈哈 2012-06-05
  • 打赏
  • 举报
回复
确实不同与传统的模板,有学习到东西,唠叨哥v5
easywang369 2012-05-30
  • 打赏
  • 举报
回复
需要研究
wangshute1986320 2012-05-29
  • 打赏
  • 举报
回复
加油~~~~~~~
加载更多回复(68)

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧