php針對模板檔案的解析與字串處理

來源:互聯網
上載者:User
本篇文章主要介紹php針對模板檔案的解析與字串處理,感興趣的朋友參考下,希望對大家有所協助。

本文執行個體講述了PHP模板解析類,具體如下:

<?phpclass 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+Mysql+jQuery實現的查詢和列表框選擇

PHP通過禁止IP頻繁訪問防止網站被防攻擊

php實現數字格式化,數字每三位加逗號的功能函數

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.