赵小黑 发表于 2017-3-22 09:57:22

php模板原理(V1)

//模板类
class template{
//存储php文件变量值
public $templatevar = array();
//模板文件目录
public $templatedir = 'data/template/';
//编译文件目录
public $compiledir = 'data/compile/';
//缓存文件目录
public $cachedir = 'data/cache/';
//赋值函数支持单变量或数组
function assign($key, $value=''){
if (is_array($key)){
foreach ($key as $tkey=>$tvalue){
$this->templatevar[$tkey] = $tvalue;
}
}else{
$this->templatevar[$key] = $value;
}
}
//编译模板
function compile($templateName){
$templateName = str_replace(strrchr($templateName, '.'), '', $templateName);
$tplName = $this->templatedir.$templateName.'.html';
$compileName = $this->compiledir.'tpl_'.$templateName.'.php';
if (file_exists($compileName) && (filemtime($compileName)+0)>time()) {//未过期
if (function_exists('file_get_contents')){
$phpCode = file_get_contents($compileName);
}else{
$fp = fopen($compileName, 'r');
while (!feof($fp)){
$phpCode .= fread($fp, 1024);
}
fclose($fp);
}
return trim($phpCode);
}
(!file_exists($tplName) || !is_readable($tplName)) && exit('模板文件加载失败');
!is_writable($this->compiledir) && exit('模板编译目录不可写');
if (function_exists('file_get_contents')){
$phpCode = file_get_contents($tplName);
}else{
$fp = fopen($tplName, 'r');
while (!feof($fp)){
$phpCode .= fread($fp, 1024);
}
fclose($fp);
}
$phpCode = stripslashes(trim($phpCode));
empty($phpCode) && exit('模板文件为空');
$tlp=array(
'/\{loop\s+(\$\w+)\s+(\$\w+)\s+(\$\w+)\s+(\$\w+)\}/i',
'/\{\/loop\}/i',
'/\{\/if\}/i',
'/\{if\s+(\S+)\}/i',
'/\{#([^\{]+)\}/i',
'/\{include\s+file=[\'|\"]?(+)[\'|\"]?\}/i',
'/\{(\$\'\"\$]+)\}/i',
'/{(\$\'\"\$]+)\.(\'\"\$]+)\}/i',
'/<!--\s+BEGIN\s+(\w+)\s+-->/i',
'/<!--\s+END\s+-->/i'
);
$php=array(
'<?php \\4=-1;foreach(\\1 as \\2=>\\3){\\4++;?>',
'<?php }?>',
'<?php }?>',
'<?php if(\\1){ ?>',
'<?php //\\1 ?>',
'<?php include("\\1");?>',
'<?php echo \\1;?>',
'<?php echo \\1[\\2];?>',
'<?php foreach($\\1 as $k=>$v){;?>',
'<?php }?>',
);
$phpCode = preg_replace($tlp, $php, $phpCode);
$globalVar = '<?php ';
foreach ($this->templatevar as $key=>$value){
if (is_array($value)){
foreach ($value as $tkey=>$tvalue){
if (is_array($tvalue)){
foreach ($tvalue as $skey=>$svalue){
$globalVar .= is_numeric($svalue) ? '$'.$key.'['.$tkey.'][\''.$skey.'\']='.$svalue.';' : '$'.$key.'['.$tkey.'][\''.$skey.'\']=\''.$svalue.'\';';
}
}else{
$globalVar .= is_numeric($tvalue) ? '$'.$key.'[\''.$tkey.'\']='.$tvalue.';' : '$'.$key.'[\''.$tkey.'\']=\''.$tvalue.'\';';
}
}
}else{
$globalVar .= is_numeric($value) ? '$'.$key.'='.$value.';' : '$'.$key.'=\''.$value.'\';';
}
}
$globalVar .= '?>';
$phpCode = $globalVar."\n\r".$phpCode;
if (function_exists('file_put_contents')){
file_put_contents($compileName, $phpCode);
}else{
$fp = fopen($compileName, 'w');
if (fwrite($fp, $phpCode) === false){
exit('模板编译失败');
}
}
return trim($phpCode);
}
//模板解析后输出
function parse($templateName, $cache=false){
$tlpName = str_replace(strrchr($templateName, '.'), '', $templateName);
$compileName = $this->compiledir.'tpl_'.$tlpName.'.php';
$cacheName = $this->cachedir.'cache_'.$tlpName.'.html';
!is_writable($this->cachedir) && exit('模板缓存目录不可写');
if (!file_exists($cacheName) || (@filemtime($cacheName)+0)<time()){//cache文件不存在或过期
$this->compile($tlpName);
ob_start();
include($compileName);
$phpCode = ob_get_contents();
ob_end_clean();
if (function_exists('file_put_contents')){
file_put_contents($cacheName, $phpCode);
}else{
$fp = fopen($cacheName, 'w');
if (fwrite($fp, $phpCode) === false){
exit('生成缓存文件失败');
}
}
return trim($phpCode);
}
if ($cache && file_exists($cacheName) && (filemtime($cacheName)+0)>=time()){//cache文件未过期
ob_start();
include($cacheName);
$phpCode = ob_get_contents();
ob_end_clean();
return trim($phpCode);
}
if (file_exists($compileName)){//编译文件存在
ob_start();
include($compileName);
$phpCode = ob_get_contents();
ob_end_clean();
return trim($phpCode);
}
}
function __destruct(){
unset($this->templatevar);
}
}

//程序文件
include('333.php');
$content = '内容123';
$arr = array(
'a'=> 'aaa',
'b' => 'bbb',
'c' => 'ccc',
);
$list = array(
array(
'XXX'=> 111,
'YYY'=> 222,
),
array(
'XXX'=> 555,
'YYY'=> 666,
),
);
$cond = true;
$c = new template;
$c->assign('content', $content);//单一变量
$c->assign($arr);//数组变量
$c->assign('cond', $cond);//IF条件
$c->assign('list', $list);//结果集
echo $c->parse('index_body.html');

//静态文件
<body>
<div>
{$content}
<div>
<div>
{$a}
<div>
<div>
{loop $list $k $v $i}
序号:{$i},姓:{$v['XXX']},名:{$v.YYY}<br>
{/loop}
</div>
<div>
{if $cond===false}
big here.
{/if}
</div>
<div>
{include file=data/template/xxx.html}
</div>
<div>
<!-- BEGIN list -->
<!-- END -->
</div>
</body>
页: [1]
查看完整版本: php模板原理(V1)