亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 網站 > 建站經驗 > 正文

PHP模板解析類實例

2024-04-25 20:38:46
字體:
來源:轉載
供稿:網友

本文實例講述了PHP模板解析類。分享給大家供大家參考。具體如下:

<?php

class template {

private $vars = array();

private $conf = '';

private $tpl_name = 'index';

//如果模板不存在 會查找當前 controller默認index模板

private $tpl_suffix = '.html';//如果CONFIG沒配置默認后綴 則顯示

private $tpl_compile_suffix= '.tpl.php';//編譯模板路徑

private $template_tag_left = '<{';//模板左標簽

private $template_tag_right = '}>';//模板右標簽

private $template_c = '';//編譯目錄

private $template_path = '';//模板完整路徑

private $template_name = '';//模板名稱 index.html

//定義每個模板的標簽的元素

private $tag_foreach = array('from', 'item', 'key');

private $tag_include = array('file');//目前只支持讀取模板默認路徑

public function __construct($conf) {

$this->conf = &$conf;

$this->template_c = $this->conf['template_config']['template_c'];//編譯目錄

$this->_tpl_suffix = $this->tpl_suffix();

}

private function str_replace($search, $replace, $content) {

if(empty($search) || empty($replace) || empty($content)) return false;

return str_replace($search, $replace, $content);

}

/**

* preg_match_all

* @param $pattern 正則

* @param $content 內容

* @return array

*/

private function preg_match_all($pattern, $content) {

if(empty($pattern) || empty($content)) core::show_error('查找模板標簽失敗!');

preg_match_all("/".$this->template_tag_left.$pattern.$this->template_tag_right."/is", $content, $match);

return $match;

}

/**

* 模板文件后綴

*/

public function tpl_suffix() {

$tpl_suffix = empty($this->conf['template_config']['template_suffix']) ?

$this->tpl_suffix :

$this->conf['template_config']['template_suffix'] ;

return $tpl_suffix;

}

/**

* 此處不解釋了

* @return

*/

public function assign($key, $value) {

$this->vars[$key] = $value;

}

/**

* 渲染頁面

* @param

* 使用方法 1

* $this->view->display('error', 'comm/');

* 默認是指向TPL模版的跟目錄,所以comm/就是 tpl/comm/error.html

* 使用方法 2

* $this->view->display('errorfile');

* 默認指向控制器固定的文件夾

* 例如你的域名是 http://heartphp/admin/index, 那么正確路徑就是tpl/admin/index/errorfile.html

* @return

*/

public function display($filename = '', $view_path = '') {

$tpl_path_arr = $this->get_tpl($filename, $view_path);//獲取TPL完整路徑 并且向指針傳送路徑以及名稱

if(!$tpl_path_arr) core::show_error($filename.$this->_tpl_suffix.'模板不存在');

//編譯開始

$this->view_path_param = $view_path;//用戶傳遞過來的模版跟目錄

$this->compile();

}

/**

* 編譯控制器

* @param

* @return

*/

private function compile() {

$filepath = $this->template_path.$this->template_name;

$compile_dirpath = $this->check_temp_compile();

$vars_template_c_name = str_replace($this->_tpl_suffix, '', $this->template_name);

$include_file = $this->template_replace($this->read_file($filepath), $compile_dirpath, $vars_template_c_name);//解析

if($include_file) {

$this->read_config() && $config = $this->read_config();

extract($this->vars, EXTR_SKIP);

[url=home.php?mod=space&uid=48608]@include[/url] $include_file;

}

}

/**

* 讀取當前項目配置文件

*/

protected function read_config() {

if(file_exists(SYSTEM_PATH.'conf/config.php')) {

@include SYSTEM_PATH.'conf/config.php';

return $config;

}

return false;

}

/**

* 解析模板語法

* @param $str 內容

* @param $compile_dirpath 模版編譯目錄

* @param $vars_template_c_name 模版編譯文件名

* @return 編譯過的PHP模板文件名

*/

private function template_replace($str, $compile_dirpath, $vars_template_c_name) {

if(empty($str)) core::show_error('模板內容為空!');

//處理編譯頭部

$compile_path = $compile_dirpath.$vars_template_c_name.$this->tpl_compile_suffix;//編譯文件

if(is_file($compile_path)) {

//$header_content = $this->get_compile_header($compile_path);

//$compile_date = $this->get_compile_header_comment($header_content);

$tpl_filemtime = filemtime($this->template_path.$this->template_name);

$compile_filemtime = filemtime($compile_path);

//echo $tpl_filemtime.'=='.date('Y-m-d H:i:s', $tpl_filemtime).'<br/>';

//echo $compile_filemtime.'=='.date('Y-m-d H:i:s', $compile_filemtime);

//如果文件過期編譯 當模板標簽有include并且有修改時 也重新編譯

//<{include file="public/left.html"}> 當修改include里的文件,非DEBUG模式時 如果不更改主文件 目前是不重新編譯include里的文件,我在考慮是否也要更改,沒想好,暫時這樣,所以在開發階段一定要開啟DEBUG=1模式 要不然修改include文件無效 。 有點羅嗦,不知道表述清楚沒

if($tpl_filemtime > $compile_filemtime || DEBUG) {

$ret_file = $this->compile_file($vars_template_c_name, $str, $compile_dirpath);

} else {

$ret_file = $compile_path;

}

} else {//編譯文件不存在 創建他

$ret_file = $this->compile_file($vars_template_c_name, $str, $compile_dirpath);

}


return $ret_file;

}

/**

* 模板文件主體

* @param string $str 內容

* @return html

*/

private function body_content($str) {

//解析

$str = $this->parse($str);

$header_comment = "Create On##".time()."|Compiled from##".$this->template_path.$this->template_name;

$content = "<? if(!defined('IS_HEARTPHP')) exit('Access Denied');/*{$header_comment}*/?>/r/n$str";

return $content;

}

/**

* 開始解析相關模板標簽

* @param $content 模板內容

*/

private function parse($content) {

//foreach

$content = $this->parse_foreach($content);

//include

$content = $this->parse_include($content);

//if

$content = $this->parse_if($content);

//elseif

$content = $this->parse_elseif($content);

//模板標簽公用部分

$content = $this->parse_comm($content);

//轉為PHP代碼

$content = $this->parse_php($content);

return $content;

}

/**

* echo 如果默認直接<{$config['domain']}> 轉成 <?php echo $config['domain']?>

*/

private function parse_echo($content) {

}

/**

* 轉換為PHP

* @param $content html 模板內容

* @return html 替換好的HTML

*/

private function parse_php($content){

if(empty($content)) return false;

$content = preg_replace("/".$this->template_tag_left."(.+?)".$this->template_tag_right."/is", "<?php $1 ?>", $content);

return $content;

}

/**

* if判斷語句

* <{if empty($zhang)}>

* zhang

* <{elseif empty($liang)}>

* liang

* <{else}>

* zhangliang

* <{/if}>

*/

private function parse_if($content) {

if(empty($content)) return false;

//preg_match_all("/".$this->template_tag_left."if/s+(.*?)".$this->template_tag_right."/is", $content, $match);

$match = $this->preg_match_all("if/s+(.*?)", $content);

if(!isset($match[1]) || !is_array($match[1])) return $content;

foreach($match[1] as $k => $v) {

//$s = preg_split("//s+/is", $v);

//$s = array_filter($s);

$content = str_replace($match[0][$k], "<?php if({$v}) { ?>", $content);

}

return $content;

}

private function parse_elseif($content) {

if(empty($content)) return false;

//preg_match_all("/".$this->template_tag_left."elseif/s+(.*?)".$this->template_tag_right."/is", $content, $match);

$match = $this->preg_match_all("elseif/s+(.*?)", $content);

if(!isset($match[1]) || !is_array($match[1])) return $content;

foreach($match[1] as $k => $v) {

//$s = preg_split("//s+/is", $v);

//$s = array_filter($s);

$content = str_replace($match[0][$k], "<?php } elseif ({$v}) { ?>", $content);

}

return $content;

}

/**

* 解析 include include標簽不是實時更新的 當主體文件更新的時候 才更新標簽內容,所以想include生效 請修改一下主體文件

* 記錄一下 有時間開發一個當DEBUG模式的時候 每次執行刪除模版編譯文件

* 使用方法 <{include file="www.phpddt.com"}>

* @param $content 模板內容

* @return html

*/

private function parse_include($content) {

if(empty($content)) return false;

//preg_match_all("/".$this->template_tag_left."include/s+(.*?)".$this->template_tag_right."/is", $content, $match);

$match = $this->preg_match_all("include/s+(.*?)", $content);

if(!isset($match[1]) || !is_array($match[1])) return $content;

foreach($match[1] as $match_key => $match_value) {

$a = preg_split("//s+/is", $match_value);

$new_tag = array();

//分析元素

foreach($a as $t) {

$b = explode('=', $t);

if(in_array($b[0], $this->tag_include)) {

if(!empty($b[1])) {

$new_tag[$b[0]] = str_replace("/"", "", $b[1]);

} else {

core::show_error('模板路徑不存在!');

}

}

}

extract($new_tag);

//查詢模板文件

foreach($this->conf['view_path'] as $v){

$conf_view_tpl = $v.$file;//include 模板文件

if(is_file($conf_view_tpl)) {

$c = $this->read_file($conf_view_tpl);

$inc_file = str_replace($this->_tpl_suffix, '', basename($file));

$this->view_path_param = dirname($file).'/';

$compile_dirpath = $this->check_temp_compile();

$include_file = $this->template_replace($c, $compile_dirpath, $inc_file);//解析

break;

} else {

core::show_error('模板文件不存在,請仔細檢查 文件:'. $conf_view_tpl);

}

}

$content = str_replace($match[0][$match_key], '<?php include("'.$include_file.'")?>', $content);

}

return $content;

}

/**

* 解析 foreach

* 使用方法 <{foreach from=$lists item=value key=kk}>

* @param $content 模板內容

* @return html 解析后的內容

*/

private function parse_foreach($content) {

if(empty($content)) return false;

//preg_match_all("/".$this->template_tag_left."foreach/s+(.*?)".$this->template_tag_right."/is", $content, $match);

$match = $this->preg_match_all("foreach/s+(.*?)", $content);

if(!isset($match[1]) || !is_array($match[1])) return $content;

foreach($match[1] as $match_key => $value) {

$split = preg_split("//s+/is", $value);

$split = array_filter($split);

$new_tag = array();

foreach($split as $v) {

$a = explode("=", $v);

if(in_array($a[0], $this->tag_foreach)) {//此處過濾標簽 不存在過濾

$new_tag[$a[0]] = $a[1];

}

}

$key = '';

extract($new_tag);

$key = ($key) ? '$'.$key.' =>' : '' ;

$s = '<?php foreach('.$from.' as '.$key.' $'.$item.') { ?>';

$content = $this->str_replace($match[0][$match_key], $s, $content);

}

return $content;

}

/**

* 匹配結束 字符串

*/

private function parse_comm($content) {

$search = array(

"/".$this->template_tag_left."//foreach".$this->template_tag_right."/is",

"/".$this->template_tag_left."//if".$this->template_tag_right."/is",

"/".$this->template_tag_left."else".$this->template_tag_right."/is",

);

$replace = array(

"<?php } ?>",

"<?php } ?>",

"<?php } else { ?>"
);

$content = preg_replace($search, $replace, $content);

return $content;

}

/**

* 檢查編譯目錄 如果沒有創建 則遞歸創建目錄

* @param string $path 文件完整路徑

* @return 模板內容

*/

private function check_temp_compile() {

//$paht = $this->template_c.

$tpl_path = ($this->view_path_param) ? $this->view_path_param : $this->get_tpl_path() ;

$all_tpl_apth = $this->template_c.$tpl_path;

if(!is_dir($all_tpl_apth)) {

$this->create_dir($tpl_path);

}

return $all_tpl_apth;

}

/**

* 讀文件

* @param string $path 文件完整路徑

* @return 模板內容

*/

private function read_file($path) {

//$this->check_file_limits($path, 'r');

if(($r = @fopen($path, 'r')) === false) {

core::show_error('模版文件沒有讀取或執行權限,請檢查!');

}

$content = fread($r, filesize($path));

fclose($r);

return $content;

}

/**

* 寫文件

* @param string $filename 文件名

* @param string $content 模板內容

* @return 文件名

*/

private function compile_file($filename, $content, $dir) {

if(empty($filename)) core::show_error("{$filename} Creation failed");

$content = $this->body_content($content);//對文件內容操作

//echo '開始編譯了=====';

$f = $dir.$filename.$this->tpl_compile_suffix;

//$this->check_file_limits($f, 'w');

if(($fp = @fopen($f, 'wb')) === false) {

core::show_error($f.'<br/>編譯文件失敗,請檢查文件權限.');

}

//開啟flock

flock($fp, LOCK_EX + LOCK_NB);

fwrite($fp, $content, strlen($content));

flock($fp, LOCK_UN + LOCK_NB);

fclose($fp);

return $f;

}

/**

* 這個檢查文件權限函數 暫時廢棄了

* @param [$path] [路徑]

* @param [status] [w=write, r=read]

*/

public function check_file_limits($path , $status = 'rw') {

clearstatcache();

if(!is_writable($path) && $status == 'w') {

core::show_error("{$path}<br/>沒有寫入權限,請檢查.");

} elseif(!is_readable($path) && $status == 'r') {

core::show_error("{$path}<br/>沒有讀取權限,請檢查.");

} elseif($status == 'rw') {//check wirte and read

if(!is_writable($path) || !is_readable($path)) {

core::show_error("{$path}<br/>沒有寫入或讀取權限,請檢查");

}

}

}

/**

* 讀取編譯后模板的第一行 并分析成數組

* @param string $filepath 文件路徑

* @param number $line 行數

* @return 返回指定行數的字符串

*/

/*

private function get_compile_header($filepath, $line = 0) {

if(($file_arr = @file($filepath)) === false) {

core::show_error($filepath.'<br/>讀取文件失敗,請檢查文件權限!');

}

return $file_arr[0];

}

*/

/**

* 分析頭部注釋的日期

* @param string $cotnent 編譯文件頭部第一行

* @return 返回上一次日期

*/

/*

private function get_compile_header_comment($content) {

preg_match("////*(.*?)/*///", $content, $match);

if(!isset($match[1]) || empty($match[1])) core::show_error('編譯錯誤!');

$arr = explode('|', $match[1]);

$arr_date = explode('##', $arr[0]);

return $arr_date[1];

}

*/

/**

* 獲取模板完整路徑 并返回已存在文件

* @param string $filename 文件名

* @param string $view_path 模板路徑

* @return

*/

private function get_tpl($filename, $view_path) {

empty($filename) && $filename = $this->tpl_name;

//遍歷模板路徑

foreach($this->conf['view_path'] as $path) {

if($view_path) {//直接從tpl跟目錄找文件

$tpl_path = $path.$view_path;

$view_file_path = $tpl_path.$filename.$this->_tpl_suffix;

} else {//根據目錄,控制器,方法開始找文件

$view_file_path = ($tpl_path = $this->get_tpl_path($path)) ? $tpl_path.$filename.$this->_tpl_suffix : exit(0);

}

if(is_file($view_file_path)) {

//向指針傳送模板路徑和模板名稱

$this->template_path = $tpl_path;//

$this->template_name = $filename.$this->_tpl_suffix;

return true;

} else {

core::show_error($filename.$this->_tpl_suffix.'模板不存在');

}

}

}

/**

* 獲取模板路徑

* @param string $path 主目錄

* @return URL D和M的拼接路徑

*/

private function get_tpl_path($path = '') {

core::get_directory_name() && $path_arr[0] = core::get_directory_name();

core::get_controller_name() && $path_arr[1] = core::get_controller_name();

(is_array($path_arr)) ? $newpath = implode('/', $path_arr) : core::show_error('獲取模板路徑失敗!') ;

return $path.$newpath.'/';

}

/**

* 創建目錄

* @param string $path 目錄

* @return

*/

private function create_dir($path, $mode = 0777){

if(is_dir($path)) return false;

$dir_arr = explode('/', $path);

$dir_arr = array_filter($dir_arr);

$allpath = '';

$newdir = $this->template_c;

foreach($dir_arr as $dir) {

$allpath = $newdir.'/'.$dir;

if(!is_dir($allpath)) {

$newdir = $allpath;

if(!@mkdir($allpath, $mode)) {

core::show_error( $allpath.'<br/>創建目錄失敗,請檢查是否有可都寫權限!');

}

chmod($allpath, $mode);

} else {

$newdir = $allpath;

}

}

return true;

}

public function __destruct(){

$this->vars = null;

$this->view_path_param = null;

}

}

希望本文所述對大家的php程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
青青久久aⅴ北条麻妃| 欧美一级黑人aaaaaaa做受| 成人乱人伦精品视频在线观看| 国产美女被下药99| 成人日韩av在线| 日韩免费在线免费观看| 国产精品久久久久久久久久久新郎| 日韩在线观看免费| 欧美丝袜美女中出在线| 中文字幕av一区二区三区谷原希美| 久久综合伊人77777蜜臀| 超碰91人人草人人干| 亚洲国产高清福利视频| 日韩av不卡电影| 欧美成人免费va影院高清| 亚洲aa中文字幕| 亚洲网站在线播放| 成人午夜激情免费视频| 久久久精品一区二区| 精品国产欧美一区二区五十路| 美女国内精品自产拍在线播放| 国产精品99久久久久久久久久久久| 久久综合久久美利坚合众国| 欧美激情xxxx| 久久久之久亚州精品露出| 亚洲国产成人久久| 国产精品扒开腿做爽爽爽的视频| 92福利视频午夜1000合集在线观看| 国产精品自在线| 成人激情免费在线| 国产欧美日韩中文字幕在线| 欧美性视频精品| 成人午夜在线视频一区| 黄色91在线观看| 一区二区福利视频| 亚洲国产欧美一区| 精品日韩中文字幕| 久久久久久尹人网香蕉| 久久久久久免费精品| 国产日产欧美a一级在线| 欧美与黑人午夜性猛交久久久| 日韩欧美在线视频| 91精品国产乱码久久久久久蜜臀| 国产在线视频欧美| www.国产精品一二区| 亚洲美女在线观看| 最近2019年手机中文字幕| 成人国产在线激情| 精品国产拍在线观看| 成人欧美一区二区三区在线| 日韩在线视频线视频免费网站| 国产精品天天狠天天看| 欧美激情第三页| 亚洲欧美日韩中文在线制服| 亚洲一区中文字幕| 成人性生交大片免费观看嘿嘿视频| 日韩欧美亚洲一二三区| 91精品国产91| 久久影视电视剧免费网站清宫辞电视| 日韩暖暖在线视频| 国产精品ⅴa在线观看h| 日韩久久午夜影院| 国产精品扒开腿做爽爽爽的视频| 精品欧美国产一区二区三区| 日韩成人av在线播放| 亚洲人成77777在线观看网| 亚洲欧美国产精品专区久久| 91午夜理伦私人影院| 亚洲深夜福利在线| 亚洲区一区二区| 日韩黄色高清视频| 欧美美女15p| 国产成人精品综合久久久| 51色欧美片视频在线观看| 久久久免费电影| 久久久久久国产精品久久| 亚洲性av在线| 日本在线观看天堂男亚洲| 国产欧美久久一区二区| 欧美日韩中文在线| 亚洲欧美另类中文字幕| 日韩麻豆第一页| 亚洲精品国产精品自产a区红杏吧| 国产亚洲精品久久久久久777| 国产日韩欧美电影在线观看| 国产精品久久久久久久久久新婚| 精品香蕉一区二区三区| 欧日韩不卡在线视频| 亚洲国产日韩欧美在线图片| 亚洲精品美女久久久久| 亚洲第一精品久久忘忧草社区| 黑人巨大精品欧美一区免费视频| 68精品久久久久久欧美| 日韩av中文在线| 亚洲天堂av网| 亚洲天堂成人在线| 国产午夜精品一区二区三区| 日韩中文字幕第一页| 九色精品免费永久在线| 欧美性感美女h网站在线观看免费| 久久久免费精品视频| 亚洲精品久久久久久久久久久久久| 国产精品爱久久久久久久| 久久久成人精品视频| 久久综合国产精品台湾中文娱乐网| 国产精品一区电影| 国产精品免费一区| 777午夜精品福利在线观看| 欧美一级在线亚洲天堂| 成人黄色av网| 欧美性生交大片免网| 免费av一区二区| 欧美亚洲另类制服自拍| 91爱视频在线| 欧美xxxx做受欧美.88| 亚洲精品丝袜日韩| 欧美做爰性生交视频| 91欧美日韩一区| 欧美日韩第一视频| 欧美性开放视频| 一区二区三区视频观看| 欧美激情第1页| 日本精品一区二区三区在线播放视频| 日韩成人小视频| 欧美精品国产精品日韩精品| 欧美午夜性色大片在线观看| 午夜精品一区二区三区在线视| 久久精品国产一区二区电影| 久久久久久久久爱| 日韩av理论片| 久久精视频免费在线久久完整在线看| 久久亚洲成人精品| 91社区国产高清| 成人网在线免费观看| 精品视频在线观看日韩| 久久精品99久久香蕉国产色戒| 亚洲精品视频播放| 97在线观看免费高清| 欧美精品激情blacked18| 日韩av中文字幕在线播放| 国产精品成人播放| 欧美日在线观看| 亚洲美女av黄| 国产脚交av在线一区二区| 国产精品久久久久久久久久三级| 国产精品久久久久影院日本| 国产成人jvid在线播放| 亚洲精品一区二三区不卡| 欧美极品美女电影一区| 亚洲毛片在线观看.| 国产精品露脸自拍| 欧美黑人国产人伦爽爽爽| 日韩av在线直播| 日韩乱码在线视频| 中文字幕欧美精品日韩中文字幕| 中文字幕在线观看日韩| 中文字幕久热精品视频在线| 欧美寡妇偷汉性猛交| 国产一区深夜福利| 亚洲最大中文字幕| 亚洲视频在线播放| 中文字幕精品一区久久久久| 日本亚洲精品在线观看| 欧美精品电影在线|