中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何自定義php模板引擎

發布時間:2021-08-31 14:27:26 來源:億速云 閱讀:123 作者:小新 欄目:開發技術

這篇文章主要介紹了如何自定義php模板引擎,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

模板引擎的思想是來源于MVC(Model View Controller)模型,即模型層、視圖層、控制器層。

在Web端,模型層為數據庫的操作;視圖層就是模板,也就是Web前端;Controller就是PHP對數據和請求的各種操作。模板引擎就是為了將視圖層和其他層分離開來,使php代碼和html代碼不會混雜在一起。因為當php代碼和html代碼混雜在一起時,將使代碼的可讀性變差,并且代碼后期的維護會變得很困難。 

大部分的模板引擎原理都差不多,核心就是利用正則表達式解析模板,將約定好的特定的標識語句編譯成php語句,然后調用時只需要include編譯后的文件,這樣就講php語句和html語句分離開來了。甚至可以更進一步將php的輸出輸出到緩沖區,然后將模板編譯成靜態的html文件,這樣請求時,就是直接打開靜態的html文件,請求速度大大加快。 

簡單的自定義模板引擎就是兩個類,第一個是模板類、第二個是編譯類。

首先是編譯類: 

class CompileClass {
 private $template;  // 待編譯文件
 private $content;  // 需要替換的文本
 private $compile_file;  // 編譯后的文件
 private $left = '{';  // 左定界符
 private $right = '}';  // 右定界符
 private $include_file = array();  // 引入的文件
 private $config;  // 模板的配置文件
 private $T_P = array();  // 需要替換的表達式
 private $T_R = array();  // 替換后的字符串
 
 public function __construct($template, $compile_file, $config) {}
 
 public function compile() {
  $this->c_include();
  $this->c_var();
  $this->c_staticFile();
  file_put_contents($this->compile_file, $this->content);
 }
 
 // 處理include
 public function c_include() {}
 
 // 處理各種賦值和基本語句
 public function c_var() {}
 
 // 對靜態的JavaScript進行解析 
 public function c_staticFile() {}
}

編譯類的大致結構就是上面那樣,編譯類的工作就是根據配置的文件,將寫好的模板文件按照規則解析,替換然后輸出到文件中。這個文件的內容是php和html混雜的,但在使用模板引擎進行開發時并不需要在意這個文件,因為我們要編寫的是模板文件,也就是html和我們自己定義的標簽混合的一個文件。這樣View和其他兩層就分離開來了。 

在這個自定義模板引擎中,我的左右定界符就是大括號,具體的解析規則就是放在__construct()中 

// 需要替換的正則表達式
$this->T_P[] = "/$this->left\s*\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\xf7-\xff]*)\s*$this->right/";
$this->T_P[] = "/$this->left\s*(loop|foreach)\s*\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\xf7-\xff]*)\s*$this->right/";
$this->T_P[] = "/$this->left\s*(loop|foreach)\s*\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\xf7-\xff]*)\s+"
  . "as\s+\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\xf7-\xff]*)$this->right/";
$this->T_P[] = "/$this->left\s*\/(loop|foreach|if)\s*$this->right/";
$this->T_P[] = "/$this->left\s*if(.*?)\s*$this->right/";
$this->T_P[] = "/$this->left\s*(else if|elseif)(.*?)\s*$this->right/";
$this->T_P[] = "/$this->left\s*else\s*$this->right/";
$this->T_P[] = "/$this->left\s*([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\xf7-\xff]*)\s*$this->right/";

// 替換后的字符串   
$this->T_R[] = "<?php echo \$\\1; ?>";
$this->T_R[] = "<?php foreach((array)\$\\2 as \$K=>\$V) { ?>";
$this->T_R[] = "<?php foreach((array)\$\\2 as &\$\\3) { ?>";
$this->T_R[] = "<?php } ?>";
$this->T_R[] = "<?php if(\\1) { ?>";
$this->T_R[] = "<?php } elseif(\\2) { ?>";
$this->T_R[] = "<?php } else { ?>";
$this->T_R[] = "<?php echo \$\\1; ?>";

上面的解析規則包含了基本的輸出和一些常用的語法,if、foreach等。利用preg_replace函數就能對模板文件進行替換。具體情況如下 

<!--模板文件-->
{$data}
{foreach $vars}
 {if $V == 1 }
  <input value="{V}">
 {elseif $V == 2}
  <input value="123123">
 {else }
  <input value="sdfsas是aa">
 {/if}
{/foreach}

{ loop $vars as $var}
 <input value="{var}">
{ /loop }
 // 解析后
<?php echo $data; ?>
<?php foreach((array)$vars as $K=>$V) { ?>
 <?php if( $V == 1) { ?>
  <input value="<?php echo $V; ?>">
 <?php } elseif( $V == 2) { ?>
  <input value="123123">
 <?php } else { ?>
  <input value="sdfsas是aa">
 <?php } ?>
<?php } ?>

<?php foreach((array)$vars as &$var) { ?>
 <input value="<?php echo $var; ?>">
<?php } ?>

編譯類的工作大致就是這樣,剩下的include和對JavaScript的解析都和這個大同小異。

然后就是模板類 

class Template {
 // 配置數組 
 private $_arrayConfig = array(
  'root' => '',  // 文件根目錄
  'suffix' => '.html',  // 模板文件后綴
  'template_dir' => 'templates',  // 模板所在文件夾
  'compile_dir' => 'templates_c',  // 編譯后存放的文件夾
  'cache_dir' => 'cache',  // 靜態html存放地址
  'cache_htm' => false,  // 是否編譯為靜態html文件
  'suffix_cache' => '.htm',  // 設置編譯文件的后綴
  'cache_time' => 7200,  // 自動更新間隔
  'php_turn' => true,  // 是否支持原生php代碼
  'debug' => 'false',
 );
 private $_value = array();  
 private $_compileTool;  // 編譯器
 static private $_instance = null;  
 public $file;  // 模板文件名
 public $debug = array();  // 調試信息
 
 public function __construct($array_config=array()) {}
 
 // 單步設置配置文件
 public function setConfig($key, $value=null) {}
 
 // 注入單個變量
 public function assign($key, $value) {}
 
 // 注入數組變量
 public function assignArray($array) {}
 
 // 是否開啟緩存
 public function needCache() {}
 
 // 如果需要重新編譯文件
 public function reCache() {}
 
 // 顯示模板
 public function show($file) {}
 
}

整個模板類的工作流程就是先實例化模板類對象,然后利用assign和assignArray方法給模板中的變量賦值,然后調用show方法,將模板和配置文件傳入編譯類的實例化對象中然后直接include編譯后的php、html混編文件,顯示輸出。簡單的流程就是這樣,詳細的代碼如下 

public function show($file) {
 $this->file = $file;
 if(!is_file($this->path())) {
  exit("找不到對應的模板文件");
 }

 $compile_file = $this->_arrayConfig['compile_dir']. md5($file). '.php';
 $cache_file = $this->_arrayConfig['cache_dir']. md5($file). $this->_arrayConfig['suffix_cache'];

 // 如果需要重新編譯文件
 if($this->reCache($file) === false) {
  $this->_compileTool = new CompileClass($this->path(), $compile_file, $this->_arrayConfig);

  if($this->needCache()) {
   // 輸出到緩沖區
   ob_start();
  }
  // 將賦值的變量導入當前符號表
  extract($this->_value, EXTR_OVERWRITE);

  if(!is_file($compile_file) or filemtime($compile_file) < filemtime($this->path())) {
   $this->_compileTool->vars = $this->_value;
   $this->_compileTool->compile();
   include($compile_file);
  }
  else {
   include($compile_file);
  }

  // 如果需要編譯成靜態文件
  if($this->needCache() === true) {
   $message = ob_get_contents();
   file_put_contents($cache_file, $message);
  }
 }
 else {
  readfile($cache_file);
 }
}

在show方法中,我首先判斷模板文件存在,然后利用MD5編碼生成編譯文件和緩存文件的文件名。然后就是判斷是否需要進行編譯,判斷的依據是看編譯文件是否存在和編譯文件的寫入時間是否小于模板文件。如果需要編譯,就利用編譯類進行編譯,生成一個php文件。然后只需要include這個編譯文件就好了。 

為了加快模板的載入,可以將編譯后的文件輸出到緩沖區中,也就是ob_start()這個函數,所有的輸出將不會輸出到瀏覽器,而是輸出到默認的緩沖區,在利用ob_get_contents()將輸出讀取出來,保存成靜態的html文件。 

具體的使用如下 

require('Template.php');

$config = array(
 'debug' => true,
 'cache_htm' => false,
 'debug' => true
);

$tpl = new Template($config);
$tpl->assign('data', microtime(true));
$tpl->assign('vars', array(1,2,3));
$tpl->assign('title', "hhhh");
$tpl->show('test');

 緩存后的文件如下 

<!DOCTYPE html>
<html>
 <head>
  <title>hhhh</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
 </head>
 <body>
  1466525760.32         <input value="1">
            <input value="123123">
            <input value="sdfsas是aa">
       
     <input value="1">
     <input value="2">
     <input value="3">
    <script src="123?t=1465898652"></script>
 </body>
</html>

感謝你能夠認真閱讀完這篇文章,希望小編分享的“如何自定義php模板引擎”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

php
AI

怀仁县| 巴东县| 衡水市| 三门峡市| 池州市| 平定县| 巨野县| 永城市| 西城区| 甘泉县| 磐安县| 镇远县| 宁城县| 林甸县| 岳池县| 桑日县| 吉木萨尔县| 安义县| 平舆县| 文登市| 砚山县| 江北区| 潞西市| 贡嘎县| 东兰县| 蓝山县| 崇义县| 铜鼓县| 宝山区| 陕西省| 衢州市| 尖扎县| 苍南县| 佛坪县| 玉环县| 静宁县| 济阳县| 张家界市| 民勤县| 肇源县| 齐河县|