使Web系统的开发与维护更加方便,从而有效的节省人力物力,受到了越来越多企业的青眯。
模板引擎是MVC模式建立过程的重要方法,开发者可以设计一套赋予含义的标签,通过技术解析处理有效的把数据逻辑处理从界面模板中提取出来,通过解读标签的含义把控制权提交给相应业务逻辑处理程序,从而获取到需要的数据,以模板设计的形式展现出来,使设计人员能把精力更多放在表现形式上。下面是我对模板引擎的认识与设计方法:
说的好听些叫模板引擎,实际就是解读模板数据的过程(个人观点^^)。通过我对建站方面的思考认识,网站在展现形式上无非归纳为单条和多条两种形式,那么我们可以设定两种对应标签(如data、list)来处理这两种情况,关键点在于解决两种标签的多层相互嵌套问题,基本适合实现80%界面形式。
解读模板的方法有多种,常用的包括字符串处理(解决嵌套稍麻烦)、正则表达式。在这里我选用的正则表达式,下面是我的处理方法(本文仅提供思路和参考代码,可能不能直接使用)。
模板文件解析类:
复制代码 代码如下:
/*
* class: 模板解析类
* author: 51JS.COM-ZMM
* date: 2011.3.1
* email: 304924248@qq.com
* blog: http://www.cnblogs.com/cnzmm/
*/
class Template {
public $html, $vars, $bTag, $eTag;
public $bFlag='{', $eFlag='}', $pfix='zmm:';
private $folder, $file;
function __construct($vars=array()) {
!empty($vars) && $this->vars = $vars;
!empty($GLOBALS['cfg_tag_prefix']) &&
$this->pfix = $GLOBALS['cfg_tag_prefix'].':';
$this->bTag = $this->bFlag.$this->pfix;
$this->eTag = $this->bFlag.'\/'.$this->pfix;
empty(Tags::$vars) && Tags::$vars = &$this->vars;
}
public function LoadTpl($tpl) {
$this->file = $this->GetTplPath($tpl);
Tags::$file = &$this->file;
if (is_file($this->file)) {
if ($this->GetTplHtml()) {
$this->SetTplTags();
} else {
exit('模板文件加载失败!');
}
} else {
exit('模板文件['.$this->file.']不存在!');
}
}
private function GetTplPath($tpl) {
$this->folder = WEBSITE_DIRROOT.
$GLOBALS['cfg_tpl_root'];
return $this->folder.'/'.$tpl;
}
private function GetTplHtml() {
$html = self::FmtTplHtml(file_get_contents($this->file));
if (!empty($html)) {
$callFunc = Tags::$prefix.'Syntax';
$this->html = Tags::$callFunc($html, new Template());
} else {
exit('模板文件内容为空!');
} return true;
}
static public function FmtTplHtml($html) {
return preg_replace('/(\r)|(\n)|(\t)|(\s{2,})/is', '', $html);
}
public function Register($vars=array()) {
if (is_array($vars)) {
$this->vars = $vars;
Tags::$vars = &$this->vars;
}
}
public function Display($bool=false, $name="", $time=0) {
if (!empty($this->html)) {
if ($bool && !empty($name)) {
if (!is_int($time)) $time = 600;
$cache = new Cache($time);
$cache->Set($name, $this->html);
}
echo $this->html; flush();
} else {
exit('模板文件内容为空!');
}
}
public function SetAssign($souc, $info) {
if (!empty($this->html)) {
$this->html = str_ireplace($souc, self::FmtTplHtml($info), $this->html);
} else {
exit('模板文件内容为空!');
}
}
private function SetTplTags() {
$this->SetPanelTags(); $this->SetTrunkTags(); $this->RegHatchVars();
}
private function SetPanelTags() {
$rule = $this->bTag.'([^'.$this->eFlag.']+)\/'.$this->eFlag;
preg_match_all('/'.$rule.'/ism', $this->html, $out_matches);
$this->TransTag($out_matches, 'panel'); unset($out_matches);
}
private function SetTrunkTags() {
$rule = $this->bTag.'(\w+)\s*([^'.$this->eFlag.']*?)'.$this->eFlag.
'((?:(?!'.$this->bTag.')[\S\s]*?|(?R))*)'.$this->eTag.'\\1\s*'.$this->eFlag;
preg_match_all('/'.$rule.'/ism', $this->html, $out_matches);
$this->TransTag($out_matches, 'trunk'); unset($out_matches);
}
private function TransTag($result, $type) {
if (!empty($result[0])) {
switch ($type) {
case 'panel' : {
for ($i = 0; $i $strTag = explode(' ', $result[1][$i], 2);
if (strpos($strTag[0], '.')) {
$itemArg = explode('.', $result[1][$i], 2);
$callFunc = Tags::$prefix.ucfirst($itemArg[0]);
if (method_exists('Tags', $callFunc)) {
$html = Tags::$callFunc(chop($itemArg[1]));
if ($html !== false) {
$this->html = str_ireplace($result[0][$i], $html, $this->html);
}
}
} else {
$rule = '^([^\s]+)\s*([\S\s]+)$';
preg_match_all('/'.$rule.'/is', trim($result[1][$i]), $tmp_matches);
$callFunc = Tags::$prefix.ucfirst($tmp_matches[1][0]);
if (method_exists('Tags', $callFunc)) {
$html = Tags::$callFunc($tmp_matches[2][0]);
if ($html !== false) {
$this->html = str_ireplace($result[0][$i], $html, $this->html);
}
} unset($tmp_matches);
}
} break;
}
case 'trunk' : {
for ($i = 0; $i $callFunc = Tags::$prefix.ucfirst($result[1][$i]);
if (method_exists('Tags', $callFunc)) {
$html = Tags::$callFunc($result[2][$i], $result[3][$i]);
$this->html = str_ireplace($result[0][$i], $html, $this->html);
}
} break;
}
default: break;
}
} else {
return false;
}
}
private function RegHatchVars() {
$this->SetPanelTags();
}
function __destruct() {}
}
?>
标签解析类:(目前暂时提供data、list两种标签的解析,说明思路)
复制代码 代码如下:
/*
* class: 标签解析类
* author: 51JS.COM-ZMM
* date: 2011.3.2
* email: 304924248@qq.com
* blog: http://www.cnblogs.com/cnzmm/
*/
class Tags {
static private $attrs=null;
static public $file, $vars, $rule, $prefix='TAG_';
static public function TAG_Syntax($html, $that) {
$rule = $that->bTag.'if\s+([^'.$that->eFlag.']+)\s*'.$that->eFlag;
$html = preg_replace('/'.$rule.'/ism', '', $html);
$rule = $that->bTag.'elseif\s+([^'.$that->eFlag.']+)\s*'.$that->eFlag;
$html = preg_replace('/'.$rule.'/ism', '', $html);
$rule = $that->bTag.'else\s*'.$that->eFlag;
$html = preg_replace('/'.$rule.'/ism', '', $html);
$rule = $that->bTag.'loop\s+(\S+)\s+(\S+)\s*'.$that->eFlag;
$html = preg_replace('/'.$rule.'/ism', '', $html);
$rule = $that->bTag.'loop\s+(\S+)\s+(\S+)\s+(\S+)\s*'.$that->eFlag;
$html = preg_replace('/'.$rule.'/ism', ' \\3) { ?>', $html);
$rule = $that->eTag.'(if|loop)\s*'.$that->eFlag;
$html = preg_replace('/'.$rule.'/ism', '', $html);
$rule = $that->bTag.'php\s*'.$that->eFlag.'((?:(?!'.
$that->bTag.')[\S\s]*?|(?R))*)'.$that->eTag.'php\s*'.$that->eFlag;
$html = preg_replace('/'.$rule.'/ism', '', $html);
return self::TAG_Execute($html);
}
static public function TAG_List($attr, $html) {
if (!empty($html)) {
if (self::TAG_HaveTag($html)) {
return self::TAG_DealTag($attr, $html, true);
} else {
return self::TAG_GetData($attr, $html, true);
}
} else {
exit('标签{list}的内容为空!');
}
}
static public function TAG_Data($attr, $html) {
if (!empty($html)) {
if (self::TAG_HaveTag($html)) {
return self::TAG_DealTag($attr, $html, false);
} else {
return self::TAG_GetData($attr, $html, false);
}
} else {
exit('标签{data}的内容为空!');
}
}
static public function TAG_Execute($html) {
ob_clean(); ob_start();
if (!empty(self::$vars)) {
is_array(self::$vars) &&
extract(self::$vars, EXTR_OVERWRITE);
}
$file_inc = WEBSITE_DIRINC.'/buffer/'.
md5(uniqid(rand(), true)).'.php';
if ($fp = fopen($file_inc, 'xb')) {
fwrite($fp, $html);
if (fclose($fp)) {
include($file_inc);
$html = ob_get_contents();
} unset($fp);
} else {
exit('模板解析文件生成失败!');
} ob_end_clean(); @unlink($file_inc);
return $html;
}
static private function TAG_HaveTag($html) {
$bool_has = false;
$tpl_ins = new Template();
self::$rule = $tpl_ins->bTag.'([^'.$tpl_ins->eFlag.']+)\/'.$tpl_ins->eFlag;
$bool_has = $bool_has || preg_match('/'.self::$rule.'/ism', $html);
self::$rule = $tpl_ins->bTag.'(\w+)\s*([^'.$tpl_ins->eFlag.']*?)'.$tpl_ins->eFlag.
'((?:(?!'.$tpl_ins->bTag.')[\S\s]*?|(?R))*)'.$tpl_ins->eTag.'\\1\s*'.$tpl_ins->eFlag;
$bool_has = $bool_has || preg_match('/'.self::$rule.'/ism', $html);
unset($tpl_ins);
return $bool_has;
}
static private function TAG_DealTag($attr, $html, $list) {
preg_match_all('/'.self::$rule.'/ism', $html, $out_matches);
if (!empty($out_matches[0])) {
$child_node = array();
for ($i = 0; $i $child_node[] = $out_matches[3][$i];
$html = str_ireplace($out_matches[3][$i], '{-->>child_node_'.$i.'}
$html = self::TAG_GetData($attr, $html, $list);
for ($i = 0; $i $html = str_ireplace('{-->>child_node_'.$i.'}
preg_match_all('/'.self::$rule.'/ism', $html, $tmp_matches);
if (!empty($tmp_matches[0])) {
for ($i = 0; $i $callFunc = self::$prefix.ucfirst($tmp_matches[1][$i]);
if (method_exists('Tags', $callFunc)) {
$temp = self::$callFunc($tmp_matches[2][$i], $tmp_matches[3][$i]);
$html = str_ireplace($tmp_matches[0][$i], $temp, $html);
}
}
}
unset($tmp_matches);
}
unset($out_matches); return $html;
}
static private function TAG_GetData($attr, $html, $list=false) {
if (!empty($attr)) {
$attr_ins = new Attbt($attr);
$attr_arr = $attr_ins->attrs;
if (is_array($attr_arr)) {
extract($attr_arr, EXTR_OVERWRITE);
$source = table_name($source, $column);
$rule = '\[field:\s*(\w+)\s*([^\]]*?)\s*\/?]';
preg_match_all('/'.$rule.'/is', $html, $out_matches);
$data_str = '';
$data_ins = new DataSql();
$attr_where = $attr_order = '';
if (!empty($where)) {
$where = str_replace(',', ' and ', $where);
$attr_where = ' where '. $where;
}
if (!empty($order)) {
$attr_order = ' order by '.$order;
} else {
$fed_name = '';
$fed_ins = $data_ins->GetFedNeedle($source);
$fed_cnt = $data_ins->GetFedCount($fed_ins);
for ($i = 0; $i $fed_flag = $data_ins->GetFedFlag($fed_ins, $i);
if (preg_match('/auto_increment/ism', $fed_flag)) {
$fed_name = $data_ins->GetFedName($fed_ins, $i);
break;
}
}
if (!empty($fed_name))
$attr_order = ' order by '.$fed_name.' desc';
}
if ($list == true) {
if (empty($source) && empty($sql)) {
exit('标签{list}必须指定source属性!');
}
$attr_rows = $attr_page = '';
if ($rows > 0) {
$attr_rows = ' limit 0,'.$rows;
}
if (!empty($sql)) {
$data_sql = $sql;
} else {
$data_sql = 'select * from `'.$source.'`'.
$attr_where.$attr_order.$attr_rows;
}
if ($pages=='true' && !empty($size)) {
$data_num = $data_ins->GetRecNum($data_sql);
$page_cnt = ceil($data_num / $size);
global $page;
if (!isset($page) || $page if ($page > $page_cnt) $page = $page_cnt;
$data_sql = 'select * from `'.$source.'`'.$attr_where.
$attr_order.' limit '.($page-1) * $size.','.$size;
$GLOBALS['cfg_page_curr'] = $page;
$GLOBALS['cfg_page_prev'] = $page - 1;
$GLOBALS['cfg_page_next'] = $page + 1;
$GLOBALS['cfg_page_nums'] = $page_cnt;
if (function_exists('list_pagelink')) {
$GLOBALS['cfg_page_list'] = list_pagelink($page, $page_cnt, 2);
}
}
$data_idx = 0;
$data_ret = $data_ins->SqlCmdExec($data_sql);
while ($row = $data_ins->GetRecArr($data_ret)) {
if ($skip > 0 && !empty($flag)) {
$data_idx != 0 &&
$data_idx % $skip == 0 &&
$data_str .= $flag;
}
$data_tmp = $html;
$data_tmp = str_ireplace('@idx', $data_idx, $data_tmp);
for ($i = 0; $i $data_tmp = str_ireplace($out_matches[0][$i],
$row[$out_matches[1][$i]], $data_tmp);
}
$data_str .= $data_tmp; $data_idx ++;
}
} else {
if (empty($source)) {
exit('标签{data}必须指定source属性!');
}
$data_sql = 'select * from `'.$source.
'`'.$attr_where.$attr_order;
$row = $data_ins->GetOneRec($data_sql);
if (is_array($row)) {
$data_tmp = $html;
for ($i = 0; $i $data_val = $row[$out_matches[1][$i]];
if (empty($out_matches[2][$i])) {
$data_tmp = str_ireplace($out_matches[0][$i], $data_val, $data_tmp);
} else {
$attr_str = $out_matches[2][$i];
$attr_ins = new Attbt($attr_str);
$func_txt = $attr_ins->attrs['function'];
if (!empty($func_txt)) {
$func_tmp = explode('(', $func_txt);
if (function_exists($func_tmp[0])) {
eval('$func_ret ='.str_ireplace('@me',
'\''.$data_val.'\'', $func_txt));
$data_tmp = str_ireplace($out_matches[0][$i], $func_ret, $data_tmp);
} else {
exit('调用了不存在的函数!');
}
} else {
exit('标签设置属性无效!');
}
}
}
$data_str .= $data_tmp;
}
}
unset($data_ins);
return $data_str;
} else {
exit('标签设置属性无效!');
}
} else {
exit('没有设置标签属性!');
}
}
static public function __callStatic($name, $args) {
exit('标签{'.$name.'}不存在!');
}
}
?>

tomakephpapplicationsfaster,关注台词:1)useopcodeCachingLikeLikeLikeLikeLikePachetoStorePreciledScompiledScriptbyTecode.2)MinimimiedAtabaseSqueriSegrieSqueriSegeriSybysequeryCachingandeffeftExting.3)Leveragephp7 leveragephp7 leveragephp7 leveragephpphp7功能forbettercodeefficy.4)

到ImprovephPapplicationspeed,关注台词:1)启用opcodeCachingwithapCutoredUcescriptexecutiontime.2)实现databasequerycachingusingpdotominiminimizedatabasehits.3)usehttp/2tomultiplexrequlexrequestsandredececonnection.4 limitsclection.4.4

依赖注入(DI)通过显式传递依赖关系,显着提升了PHP代码的可测试性。 1)DI解耦类与具体实现,使测试和维护更灵活。 2)三种类型中,构造函数注入明确表达依赖,保持状态一致。 3)使用DI容器管理复杂依赖,提升代码质量和开发效率。

databasequeryOptimizationinphpinvolVolVOLVESEVERSEVERSTRATEMIESOENHANCEPERANCE.1)SELECTONLYNLYNESSERSAYCOLUMNSTORMONTOUMTOUNSOUDSATATATATATATATATATATRANSFER.3)

phpisusedforsenderemailsduetoitsbuilt-inmail()函数andsupportiveLibrariesLikePhpMailerandSwiftMailer.1)usethemail()functionforbasicemails,butithasimails.2)butithasimimitations.2)

PHP性能瓶颈可以通过以下步骤解决:1)使用Xdebug或Blackfire进行性能分析,找出问题所在;2)优化数据库查询并使用缓存,如APCu;3)使用array_filter等高效函数优化数组操作;4)配置OPcache进行字节码缓存;5)优化前端,如减少HTTP请求和优化图片;6)持续监控和优化性能。通过这些方法,可以显着提升PHP应用的性能。

依赖性注射(DI)InphpisadesignPatternthatManages和ReducesClassDeptions,增强量产生性,可验证性和Maintainability.itallowspasspassingDepentenciesLikEdenceSeconnectionSeconnectionStoclasseconnectionStoclasseSasasasasareTers,interitationApertatingAeseritatingEaseTestingEasingEaseTeStingEasingAndScalability。

cachingimprovesphpermenceByStorcyResultSofComputationsorqucrouctationsorquctationsorquickretrieval,reducingServerLoadAndenHancingResponsetimes.feftectivestrategiesinclude:1)opcodecaching,whereStoresCompiledSinmememorytssinmemorytoskipcompliation; 2)datacaching datacachingsingMemccachingmcachingmcachings


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

禅工作室 13.0.1
功能强大的PHP集成开发环境

WebStorm Mac版
好用的JavaScript开发工具

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)