PHPテンプレート解析クラス
-
- class template {
- private $vars = array();
- private $conf = '';
- private $tpl_name = 'index';// テンプレートが存在しない場合、現在のコントローラーが検索されます デフォルトのインデックス テンプレート
- private $tpl_suffix = '.html';//CONFIG がデフォルトのサフィックスで構成されていない場合、それが表示されます
- private $tpl_compile_suffix= '.tpl.php';//テンプレートをコンパイルしますpath
- 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();
- }
-
-
-
- プライベート関数 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 Regular
- * @param $content コンテンツ
- * @return array
- */
-
- プライベート関数 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->gt;view_path_param = $view_path;//ユーザーによって渡されたテンプレートとディレクトリ
- $this->compile();
-
- }
-
- /**
- * コンパイルコントローラー
- * @param
- * @return
- */
- プライベート関数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);//Parse
- 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;
- }
- }
-
- /**
- * 現在のプロジェクト構成ファイルを読み取ります
- */
- 保護関数 read_config() {
- if(file_exists(SYSTEM_PATH) .'conf/config.php')) {
- @include SYSTEM_PATH.'conf/ config.php';
- return $config;
- }
-
- return false;
- }
- /**
- * テンプレート構文の解析
- * @param $str content
- * @param $compile_dirpath テンプレートのコンパイル ディレクトリ
- * @param $vars_template_c_name テンプレートのコンパイル ファイル名
- * @return コンパイル済みの PHP テンプレート ファイル名
- */
- プライベート関数 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->gt;get_compile_header( $コンパイル_パス);
- //$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).'
'; - //echo $compile_filemtime.'== ' .date('Y-m-d H:i:s', $compile_filemtime);
- //ファイルの有効期限が切れている場合は、コンパイルし、テンプレート タグに include が含まれているため、再コンパイルも行われます
- //<{include file="public/ left.html"}> インクルード内のファイルを変更する場合、非DEBUGモードではメインファイルを変更しないと現状インクルード内のファイルは再コンパイルされません。これも変更するか検討中です。とりあえず考えてなかったので、開発段階では必ずDEBUG=1モードをONにしてください。そうしないとインクルードファイルの変更が無効になります。有点罗嗦,不知道表述明確没
- 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 content
- * @return html
- */
- private function body_content($str) {
- //解析
- $str = $this->parse($str);
-
- $header_comment = "作成日##" .time()."|Compiled from##".$this->template_path.$this->template_name;
- $content = " if(!define('IS_HEARTPHP')) exit('アクセスが拒否されました');/*{$header_comment}*/?>rn$str";
-
- return $content;
- }
-
- /**
- * 関連するテンプレート タグの解析を開始します
- * @param $content テンプレート コンテンツ
- */
- プライベート関数 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']}> の場合、 に変換されます。*/
- private function parse_echo($content) {
-
- }
-
- /**
- * PHP に変換します
- * @param $content html テンプレートのコンテンツ
- * @return html HTML を置き換えます
- */
- プライベート関数 parse_php($content){
- if(empty($content)) return false;
- $content = preg_replace("/".$this->template_tag_left. "(.+?)".$this->template_tag_right."/is", "", $content);
-
- return $content;
- }
- /**
- * if判断语句
- * <{if empty($zhang)}>
- * zhang
- * <{elseif empty($liang)}>
- * liang
- * <{else}>
- *張良
- * <{/if}>
- */
- プライベート関数 parse_if($content) {
- if(empty($content)) return false;
- //preg_match_all("/".$this->template_tag_left."ifs+(.*?)".$this ->template_tag_right."/is", $content, $match);
-
- $match = $this->preg_match_all("ifs+(.*?)", $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], "", $content);
- }
-
- return $content;
- }
-
- private function parse_elseif($content) {
- if(empty($content)) return false;
- //preg_match_all("/".$ this->template_tag_left."elseifs+(.*?)".$this->template_tag_right."/is", $content, $match);
- $match = $this->preg_match_all("elseifs+(.* ?)", $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], "", $ 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."includes+(.*?)".$this->template_tag_right."/is", $content, $match);
- $match = $this->preg_match_all("includes+(.* ?)", $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;//模板文件
- 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], '', $content);
- }
-
- return $content;
-
- }
- /**
- * foreach を解析します
- * 使用方法 <{foreach from=$lists item=value key=kk}>
- * @param $content template content
- * @return html 解析されたコンテンツ
- */
- private function parse_foreach($content) {
- if(empty($content)) return false;
-
- //preg_match_all("/" .$this->template_tag_left."foreachs+(.*?)".$this->template_tag_right."/is", $content, $match);
- $match = $this->preg_match_all("foreachs+( .*?)", $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 = '';
- $content = $this-> ;str_replace($match[0][$match_key], $s, $content);
-
- }
-
- return $content;
- }
-
- /**
- * 一致文字列の終わり
- */
- プライベート関数 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(
- "",
- "",
- ""
- );
- $content = preg_replace($ search、$replace、$content);
- return $content;
- }
- /**
- * コンパイルディレクトリを確認し、作成されていない場合は再帰的にディレクトリを作成します
- * @param string $path ファイルのフルパス
- * @return テンプレートの内容
- */
- プライベート関数 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 テンプレートの内容
- */
- プライベート関数 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 ファイル名
- */
- プライベート関数compile_file($filename, $content, $dir) {
- if(empty($filename)) core::show_error("{$filename} 作成に失敗しました");
-
- $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.'
编译文件失败,请检查文件权限。 ');
- }
- //开启flock
- flock($fp, LOCK_EX + LOCK_NB);
- fwrite($fp, $content, strlen($content));
- flock($fp, LOCK_UN + LOCK_NB);
- fclose ($fp);
-
- return $f;
- }
-
- /**
- * ファイルのパーミッションをチェックする機能は一時的に廃止されます
- * @param [$path] [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}
没有書入权限,请检查。");
- } elseif(!is_readable($path) ) && $status == 'r') {
- core::show_error("{$path}
没有读取权限,请检查。");
- } elseif($status == 'rw' ) {//書き込みと読み取りをチェック
- if(!is_writable($path) || !is_readable($path)) {
- core::show_error("{$path}
無し写入または读取权制限,请检查");
- }
- }
-
-
- }
-
- /* *
- * コンパイルされたテンプレートの最初の行を読み取り、配列に解析します
- * @param string $filepath ファイルパス
- * @param number $line 行数
- * @return は指定された行数の文字列を返します
- */
- /*
- プライベート関数 get_compile_header($filepath, $line = 0) {
-
- if(($file_arr = @file($filepath)) === false) {
- core::show_error( $filepath.'
读取文件失败,请检查文件权限!');
- }
- return $file_arr[0];
- }
- */
-
- /**
- * ヘッダーコメントの分析日
- * @param string $cotnent コンパイルされたファイルのヘッダーの最初の行
- * @return 最後の日付を返します
- */
- /*
- プライベート関数 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 の結合パス
- */
- プライベート関数 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
- */
- プライベート関数 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.'
ディレクトリの作成に失敗しました。書き込み権限があるかどうかを確認してください。 ');
- }
- chmod($allpath, $mode);
- } else {
- $newdir = $allpath;
- }
- }
- return true;
- }
-
- public function __destruct(){
- $this-> vars = null;
- $this->view_path_param = null;
- }
-
- };
コードをコピー
|