zuitu团购模板引擎浅析

     接触过最土的朋友应该很熟悉  最土模板解析功能主要由 include/function/template.php文件完成 ,就是通过正则的替换,捕获来完成而已,与smarty的原理类似。下面分析下他的正则替换。

         在template.php文件中有这段代码

 

 1 function __parse($tFile,$cFile) {
 2 
 3     $fileContent = false;
 4 
 5     if(!($fileContent = file_get_contents($tFile)))
 6         return false;
 7 
 8     $fileContent = preg_replace( '/^(\xef\xbb\xbf)/', '', $fileContent ); //EFBBBF   
 9     $fileContent = preg_replace("/\<\!\-\-\s*\\\$\{(.+?)\}\s*\-\-\>/ies", "__replace('<?php \\1; ?>')", $fileContent);
10     $fileContent = preg_replace("/\{(\\\$[a-zA-Z0-9_\[\]\\\ \-\'\,\%\*\/\.\(\)\>\'\"\$\x7f-\xff]+)\}/s", "<?php echo \\1; ?>", $fileContent);
11     $fileContent = preg_replace("/\\\$\{(.+?)\}/ies", "__replace('<?php echo \\1; ?>')", $fileContent);
12     $fileContent = preg_replace("/\<\!\-\-\s*\{else\s*if\s+(.+?)\}\s*\-\-\>/ies", "__replace('<?php } else if(\\1) { ?>')", $fileContent);
13     $fileContent = preg_replace("/\<\!\-\-\s*\{elif\s+(.+?)\}\s*\-\-\>/ies", "__replace('<?php } else if(\\1) { ?>')", $fileContent);
14     $fileContent = preg_replace("/\<\!\-\-\s*\{else\}\s*\-\-\>/is", "<?php } else { ?>", $fileContent);
15 
16     for($i = 0; $i < 5; ++$i) {
17         $fileContent = preg_replace("/\<\!\-\-\s*\{loop\s+(\S+)\s+(\S+)\s+(\S+)\s*\}\s*\-\-\>(.+?)\<\!\-\-\s*\{\/loop\}\s*\-\-\>/ies", "__replace('<?php if(is_array(\\1)){foreach(\\1 AS \\2=>\\3) { ?>\\4<?php }}?>')", $fileContent);
18         $fileContent = preg_replace("/\<\!\-\-\s*\{loop\s+(\S+)\s+(\S+)\s*\}\s*\-\-\>(.+?)\<\!\-\-\s*\{\/loop\}\s*\-\-\>/ies", "__replace('<?php   if(is_array(\\1)){foreach(\\1 AS \\2) { ?>\\3<?php }}?>')", $fileContent);
19         $fileContent = preg_replace("/\<\!\-\-\s*\{if\s+(.+?)\}\s*\-\-\>(.+?)\<\!\-\-\s*\{\/if\}\s*\-\-\>/ies", "__replace('<?php if(\\1){?>\\2<?php }?>')", $fileContent);
20     
21     }
22     //Add for call <!--{include othertpl}-->
23     $fileContent = preg_replace("#<!--\s*{\s*include\s+([^\{\}]+)\s*\}\s*-->#i", '<?php include template("\\1");?>', $fileContent);
24 
25     //Add value namespace
26     if(!file_put_contents($cFile,$fileContent))    
27         return false;
28     
29 
30     return true;
31 }
32 
33 function __replace($string) {
34     return str_replace('\"', '"', $string);
35 }

现在对正则替换进行分析:

第8行

$fileContent = preg_replace( '/^(\xef\xbb\xbf)/', '', $fileContent ); 

是过滤掉windows平台下utf8文件的特殊字符 ï  » ¿

第九行

$fileContent = preg_replace("/\<\!\-\-\s*\\\$\{(.+?)\}\s*\-\-\>/ies", "__replace('<?php \\1; ?>')", $fileContent);

规则浅析:

<!--(0+个空白字符)${除换行符外任何字符}0+个空白字符-->

 

结合模式修正ies

 

i不区分大小写 

 

将替换后的内容作为php代码执行 让__replace()作为php代码     执行取得结果 而不是得到单纯的字符串 相当于eval(替换后的内容)

 

s就不说了

 

就是<!--${php代码}-->   在{}里执行任何php代码

第10行

 $fileContent = preg_replace("/\{(\\\$[a-zA-Z0-9_\[\]\\\ \-\'\,\%\*\/\.\(\)\>\'\"\$\x7f-\xff]+)\}/s", "<?php echo \\1; ?>", $fileContent);

html模板文件里: {$代码内容(可以包含中文)}  =>   <?php echo {}之间的内容 ?>

eg:{$a}对应<?php echo $a; ?>

 

用于显示内容

第11行

$fileContent = preg_replace("/\\\$\{(.+?)\}/ies", "__replace('<?php echo \\1; ?>')", $fileContent);

模板代码: ${代码}   =><?php echo 代码 ?> 

eg: ${ $a}对应 <?php echo  $a; ?>

第12行

 $fileContent = preg_replace("/\<\!\-\-\s*\{else\s*if\s+(.+?)\}\s*\-\-\>/ies", "__replace('<?php } else if(\\1) { ?>')", $fileContent);

模板里的<!-- {else if ‘a’=’a’}-->     转为<?php } else if('a'=='a') { ?>

第13行

 

$fileContent = preg_replace("/\<\!\-\-\s*\{elif\s+(.+?)\}\s*\-\-\>/ies", "__replace('<?php } else if(\\1) { ?>')", $fileContent);

 

模板里 <!-- {elif  'a'='a'} -->  转为  <?php } else if('a'='a') { ?>

第14行

 

$fileContent = preg_replace("/\<\!\-\-\s*\{else\}\s*\-\-\>/is", "<?php } else { ?>", $fileContent);

 

模板里 <!-- {else} -->   转为  <?php } else { ?>

第17行

 $fileContent = preg_replace("/\<\!\-\-\s*\{loop\s+(\S+)\s+(\S+)\s+(\S+)\s*\}\s*\-\-\>(.+?)\<\!\-\-\s*\{\/loop\}\s*\-\-\>/ies", "__replace('<?php if(is_array(\\1)){foreach(\\1 AS \\2=>\\3) { ?>\\4<?php }}?>')", $fileContent);

模板中

<!-- {loop $arr  $k  $v} -->

"php内容举例"

<!--{/loop} -->

替换后

<?php if(is_array($arr)){foreach($arr AS $k=>$v) { ?>

"php内容举例"

<?php }}?>

 

第18行与第17行差不多就是少了$k其他完全一样

 

 

 

第19行

$fileContent = preg_replace("/\<\!\-\-\s*\{if\s+(.+?)\}\s*\-\-\>(.+?)\<\!\-\-\s*\{\/if\}\s*\-\-\>/ies", "__replace('<?php if(\\1){?>\\2<?php }?>')", $fileContent);

模板中:

<!-- {if 'a' } -->

'b'

<!-- {/if}-->

替换后

<?php if('a' ){?>

'b'

<?php }?>


大家在测试时件最好建几个文件(模板文件,解析文件,生成的php文件)以便于测试

正在看最土,欢迎有兴趣的朋友共同探讨!

转载请标明出处!

posted @ 2013-05-27 21:23  H&K  阅读(1436)  评论(0编辑  收藏  举报