曾经开发PHP项目时候,需要实现页面静态化批量产生,比如很多详细页面和发送HTML邮件页面.这时候采用SMARTY等模板引擎就很不合适.我动手开发了一个简化的快速模板引擎.当然功能是有限的,该类用来生成静态页面和HTML邮件,目前可以支持循环的数据.该类仅支持一层的IF,IF语句要写条件快,IF判断在模板外面完成.该类不支持嵌套的循环,一次调用只能支持一个IF和循环.
下面是该类的定义代码:
class PageStatic {
//---设置全局变量
// Holds all assigned variable names and values.
//var $VAR = array();
// 读取的模板HTMl
var $HTML ='';
// 读取的for循环HTML
var $forHTML ='';
//整合的结果for循环HTML
var $result_forHtml ='';
// 读取的if条件HTML
var $ifHTML ='';
//整合的结果if条件HTML
var $result_ifHtml ='';
//构造函数
function PageStatic($pathToTemplates=''){
if (!empty($pathToTemplates)) {
$this->readTemplate ($pathToTemplates);
}
return $this;
}
/****************************************************
函数 parse_internalIf ($forchar)
$forchar--if条件的在模板中的名称
提取这部分html code
such as {ifwarnBlock}
......
{/ifwarnBlock}
****************************************/
function parse_internalIf($forchar){
$s_pos =0;
while(true)
{
$s_pos = strpos($this->HTML,'{'.$forchar.'}',$s_pos);
if ($s_pos === false) break;
$e_pos = strpos($this->HTML,'{/'.$forchar.'}',$s_pos);
if ($e_pos === false) break;
$Service_str = substr($this->HTML,$s_pos,$e_pos-$s_pos);
$s_pos = $e_pos;
}
$this->ifHTML=str_replace('{'.$forchar.'}','',$Service_str);
}
/****************************************************
函数 setIf()
加给$result_ifHtml
****************************************/
function setIf(){
$this->result_ifHtml .=$this->ifHTML;
}
/****************************************************
函数 clearIf()
清空$this->ifHTML
****************************************/
function clearIf(){
$this->ifHTML ='';
}
/****************************************************
函数 clearResultIf()
清空$result_ifHtml
****************************************/
function clearResultIf(){
$this->result_ifHtml ='';
}
/****************************************************
函数 complier_internalIf($forchar,$contidion=true)
$forchar--if条件的在模板中的名称
替换这部分html code,用在if结束后
****************************************/
function complier_internalIf($forchar,$contidion=true){
if($contidion){
$this->HTML=ereg_replace ('{'.$forchar.'}'.'(.*)'.'{/'.$forchar.'}',$this->result_ifHtml,$this->HTML);
}else{
$this->HTML=ereg_replace ('{'.$forchar.'}'.'(.*)'.'{/'.$forchar.'}','',$this->HTML);
}
$this->clearResultIf();
$this->clearIf();
}
/****************************************************
函数 parse_internalFor ($forchar)
$forchar--for循环的在模板中的名称
提取这部分html code
such as {warnBlock}
......
{/warnBlock}
****************************************/
function parse_internalFor($forchar){
$s_pos =0;
while(true)
{
$s_pos = strpos($this->HTML,'{'.$forchar.'}',$s_pos);
if ($s_pos === false) break;
$e_pos = strpos($this->HTML,'{/'.$forchar.'}',$s_pos);
if ($e_pos === false) break;
$Service_str = substr($this->HTML,$s_pos,$e_pos-$s_pos);
$s_pos = $e_pos;
}
$this->forHTML=str_replace('{'.$forchar.'}','',$Service_str);
}
/****************************************************
函数 setFor()
加给this->result_forHtml
****************************************/
function setFor(){
$this->result_forHtml .=$this->forHTML;
}
/****************************************************
函数 clearFor()
清空$this->forHTML
****************************************/
function clearFor(){
$this->forHTML ='';
}
/****************************************************
函数 clearResultFor()
清空$this->result_forHtml
****************************************/
function clearResultFor(){
$this->result_forHtml ='';
}
/****************************************************
函数 complier_internalFor($forchar)
$forchar--for循环的在模板中的名称
替换这部分html code,用在循环结束后
****************************************/
function complier_internalFor($forchar){
$this->HTML=ereg_replace ('{'.$forchar.'}'.'(.*)'.'{/'.$forchar.'}',$this->result_forHtml,$this->HTML);
$this->clearResultFor();
$this->clearFor();
}
/****************************************************
函数 assign ($tplkey, $style=0,$rest='')
$tplkey赋入替换变量数组,$style替换的类型,0--模板HTMl,
1--读取的for循环HTML,2--读取的if循环HTML
$rest--当$tplkey是变量时候,$rest是替换的值
****************************************/
function assign ($tplkey, $style = 0,$rest='') {
// print_r($tplkey);
if (gettype ($tplkey) == 'array') {
reset ($tplkey);
while (list($key,$val) = each ($tplkey)) {
if (!empty($key)) {
$key = '{'.$key.'}';
if($style == 1){
$this->forHTML=str_replace($key,$val,$this->forHTML);
}elseif($style == 2){
$this->ifHTML=str_replace($key,$val,$this->ifHTML);
}elseif($style == 0){
$this->HTML=str_replace($key,$val,$this->HTML);
}else{
return false;
}
}
}
}else {
if (!empty($tplkey)) {
$tplkey = '{'.$tplkey.'}';
if($style == 1){
$this->forHTML=str_replace($tplkey,$rest,$this->forHTML);
}elseif($style == 2){
$this->ifHTML=str_replace($tplkey,$rest,$this->ifHTML);
}elseif($style == 0){
$this->HTML=str_replace($tplkey,$rest,$this->HTML);
}else{
return false;
}
}
}
}
/****************************************************
函数readTemplate($filename='')
读取模板文件,保存到html代码中
****************************************/
function readTemplate($filename=''){
$htmlContent='';
@$handle1 = fopen($filename,"r");
do
{
@$data1 = fread($handle1, 9216);
if (strlen($data1) == 0) {
break;
}
$htmlContent .= $data1;
}
while(true);
$this->HTML=$htmlContent;
}
/****************************************************
函数load($style=0,$filename='')
输出结果HTML,$style=0是输出HTML,用来发送HTML邮件,
$style=1是输出HTML写入指定文件,创建html页面
****************************************/
function load($style=0,$filename=''){
if($style==0){
return $this->HTML;
}else{
$this->writeover($filename);
return true;
}
}
/****************************************************
函数writeover($filename,$data,$method="rb+",$iflock=1)
在制定目录编写静态文件
****************************************/
function writeover($filename,$method="rb+",$iflock=1)
{
@touch($filename);
$handle=@fopen($filename,$method);
if($iflock){
flock($handle,LOCK_EX);
}
fputs($handle,$this->HTML);
if($method=="rb+") ftruncate($handle,strlen($this->HTML));
fclose($handle);
}
}//end of class
该类的使用方法如下:
//然后具体的调用方法,注意里面有循环和单重的条件判断.
$productList=$oColorProduct ->getProductList("cProductNumber,cProductName,cProductStyle,cProductPic1,cProductText,dCreatDate",0, 1,"cProductId='".$cProductId."'");
$staticPage = new PageStatic('detail/detail.htm');//提取模板页面
$staticPage->assign(array(//赋值,类型为1代表循环,2代表if条件,0代表默认.
'cProductNumber'=>$productList[0]['cProductNumber'],
'cProductName'=>$productList[0]['cProductName'],
'cProductStyle'=>$productList[0]['cProductStyle'],
'dCreatDate'=>$productList[0]['dCreatDate'],
'cProductText'=>$productList[0]['cProductText'],
));
$staticPage->parse_internalIf('ifimg');//分析条件判断的部分
$staticPage->assign ('cProductPic1', 2,$productList[0]['cProductPic1']) ;//赋值,类型为1代表循环,2代表if条件,0代表默认.
$staticPage->setIf();//加入条件的内容
if(trim($productList[0]['cProductPic1'])!=''){//判断内容写在PHP中
$staticPage->complier_internalIf('ifimg',true);//进行整页替换if快
}else{
$staticPage->complier_internalIf('ifimg',false);
}
$parentCategoryList=$oColorCategory->getParentCategory();
foreach($parentCategoryList as $k => $sub){
$staticPage->parse_internalFor('categoryBlock');//必须写在循环中,分析循环的部分
$staticPage->assign(array(
'cProductCategoryName'=>trim($sub['cProductCategoryName']),
'cProductCategoryID'=>trim($sub['cProductCategoryID']),
),1);//赋值,类型为1代表循环,2代表if条件,0代表默认.
$staticPage->setFor();//必须写在循环中,加入循环的部分
}
$staticPage->complier_internalFor('categoryBlock');//必须写在循环外,进行整页替换循环快
$staticPage->load(1,'detail/'.$cProductId.'.htm');//最后加载一个新生成的静态页面,如果参数为空
//$mailHTML=$staticPage->load();//返处理后的HTML代码,可以用于发送HTML邮件.
最后给出这个范例用到的静态模板页面的标签用法.
先看下面这个detail.htm页面作为模板
<HTML><HEAD><TITLE></TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META http-equiv=Pragma content=no-cache><LINK href="imgs/165.css"
type=text/css rel=stylesheet>
<META content="MSHTML 6.00.2600.0" name=GENERATOR></HEAD>
<BODY class=body text=#000000 bgColor=#ffffff leftMargin=0
background=imgs/background.gif topMargin=0>
<TABLE cellSpacing=0 cellPadding=0 width=1000 align=center border=0>
<TBODY>
<TR>
<TD vAlign=top align=left>
<TABLE cellSpacing=0 cellPadding=0 width=1000 align=center border=0
dwcopytype="CopyTableCell">
<TBODY>
<TR>
<TD vAlign=top align=left><IMG height=119
src="imgs/1.gif" width=1000 useMap=#MapMap
border=0></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD vAlign=top align=left> </TD>
</TR>
<TR>
<TD vAlign=top align=left>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR vAlign=top align=left>
<TD vAlign=top align=left width="22%"
background=imgs/zuodi2.gif>
<TABLE cellSpacing=0 cellPadding=0 width=100 border=0>
<TBODY>
<TR>
<TD><IMG height=72 src="imgs/ebiz_l_pic1.gif"
width=213></TD></TR>
<TR>
<TD style="PADDING-LEFT: 15px"
background=imgs/cebanner.gif>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG
src="imgs/black.gif"></TD></TR></TBODY></TABLE>
<TABLE class=ProductCategoryExhibitLadder_bg cellSpacing=0
width="100%" border=0>
<TBODY>
{categoryBlock}
<TR id=ProductCategoryExhibitLadder1_tr1>
<TD id=ProductCategoryExhibitLadder1_td1 height=25>
<DIV class=ProductCategoryExhibitLadder_div
id=ProductCategoryExhibitLadder_button
width="100%"><IMG style="CURSOR: hand"
src="imgs/minus.gif" border=0> <A
class=ProductCategoryExhibitLadder_a
href="../prolist.php?cProductCategoryID={cProductCategoryID}">{cProductCategoryName}</A>
</DIV></TD></TR>
{/categoryBlock}
<TR>
<TD align=middle
height=30> </TD></TR></TABLE>
</TD></TR>
<TR>
<TD style="PADDING-LEFT: 0px" vAlign=top align=left
background=imgs/cebanner.gif><IMG height=25
src="imgs/chanpindi.gif"
width=213></TD></TR></TABLE></TD>
<TD width="78%" background=imgs/youdi.gif>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD vAlign=top align=left
background=imgs/youdi.gif><TABLE cellSpacing=0
cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width="5%"> </TD>
<TD vAlign=top align=left width="73%">
<TABLE cellSpacing=0 cellPadding=0 width="98%"
align=center border=0>
<TBODY>
<TR>
<TD>
<TABLE width="90%" border=0>
<TBODY>
<TR>
<TD align=left>
<TABLE cellPadding=2 border=0>
<TBODY>
<TR>
<TD class=ProductInfoExhibit_title vAlign=top
align=right width=100> 商品编号</TD>
<TD class=ProductInfoExhibit_td
style="WORD-BREAK: break-all">{cProductNumber}</TD></TR>
<TR>
<TD class=ProductInfoExhibit_title vAlign=top
align=right width=100>商品名称</TD>
<TD class=ProductInfoExhibit_td
style="WORD-BREAK: break-all">{cProductName}</TD></TR>
<TR>
<TD class=ProductInfoExhibit_title vAlign=top
align=right width=100>商品型号</TD>
<TD class=ProductInfoExhibit_td
style="WORD-BREAK: break-all">{cProductStyle}</TD></TR>
<TR>
<TD class=ProductInfoExhibit_title vAlign=top
align=right width=100>上价日期</TD>
<TD class=ProductInfoExhibit_td
style="WORD-BREAK: break-all">{dCreatDate}</TD></TR>
</TBODY></TABLE></TD>
<TD vAlign=top align=left>
{ifimg}
<IMG
height=105 src="../upload/{cProductPic1}" width=139 border=0>
{/ifimg}
</TD></TR></TBODY></TABLE>
<TABLE width="90%">
<TBODY>
<TR>
<TD colSpan=2>
<TABLE width="100%">
<TBODY>
<TR>
<TD bgColor=#cccccc
colSpan=4></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD bgColor=#cccccc></TD></TR>
<TR>
<TD style="WORD-BREAK: break-all">商品描述
<TABLE cellSpacing=0 cellPadding=0 width="90%"
border=0>
<TBODY>
<TR>
<TD>
{cProductText}
</TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR>
<CENTER><A
href="javascript:window.close();"></A></CENTER></TD></TR>
<TR>
<TD height=30></TD></TR></TBODY></TABLE></TD>
<TD vAlign=top align=left width="22%">
<TABLE height=226 cellSpacing=0 cellPadding=0 width=157
border=0>
<TBODY>
<TR>
<TD vAlign=top align=right>
</TD>
</TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD vAlign=top align=left background=imgs/di3.gif>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR vAlign=top align=left>
<TD width="1%" background=""> </TD>
<TD width="99%">
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD vAlign=top align=left> </TD>
</TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></BODY></HTML>