摘要:體現了業務與顯示的分離,盡量分離。就負責判斷條件,并取出數據來。顯示的工作盡量靠前頁面緩存緩存,重要概念。減輕了數據庫的壓力??刂凭植坎痪彺嬖跇撕炛锌刂疲摌撕灢痪彺?。模板調用特殊方法使用對象注冊的方式來解決。文件命名函數名定
模板
數據與表現層的標簽分離
smarty是PHP 與 HTML代碼的分離
小型模板類$smarty 的工作流程:
把需要顯示的全局變量,賦值塞到對象內部的屬性上,一個數組中.
編譯模板,把{$標簽},解析成相應的代碼
引入編譯后的PHP文件
使用smarty的步驟:
smarty是一個類,要使用,需要先引入并實例化
assign賦值
display --> 編譯到輸出
smarty缺點:
編譯模板,需要消耗時間
要把變量再重新賦值一份(又倒騰一次,放在對象的屬性上)
PHP文件 * 區分 模板文件和 PHP文件,把模板和編譯后的結果,放置在不同的目錄中. * 用2個不同的屬性來記錄 不同的目錄 */ class Tmp { public $template_dir = ""; // 模版文件所在的路徑 public $compile_dir = ""; // 模板編譯后存在的路徑 public $tpl_var = array(); // 接受外部的變量 /** * 存儲全局變量 * @param {String} $key 變量名 * @param {Mixin} $val 變量值 */ public function assign( $key, $val ) { $this->tpl_var[$key] = $val; } /** * 調用 compile模板,和自動引入 * @param {String} $template 模板文件名 */ public function display( $template ) { $comp = $this->compile($template); include($comp); } /** * 編譯 * @param {String} $template 模板文件名 (需要編譯的模板文件的文件名) * @return {String} $comp 編譯后的文件路徑 * * 把指定的模板內容讀取,再編譯成PHP文件 * * 最終外部執行的是,編譯后的文件 */ public function compile( $template ) { // 讀取模板內容 $tmp = $this->template_dir . "/" . $template; $scoure = file_get_contents($tmp); // 替換模板內容 $scoure = str_replace("{$", "tpl_var["", $scoure); $scoure = str_replace("}", ""];?>", $scoure); // 把編譯后的內容保存成編譯后的文件 $comp = $this->compile_dir . "/". $template . ".php"; // 判斷模板是否已經存在, 加上通過 文件修改的時間來判斷,模板是否已經被修改過 if ( file_exists($comp) && filemtime($tmp) < filemtime($comp) ) { return $comp; } file_put_contents($comp, $scoure); return $comp; } } ?>引入賦值和標簽語法
smarty典型使用流程
template_dir = "./templates"; $smarty->compile_dir = "./compile"; // 賦值 $smarty->assign("title", "T"); $smarty->assign("content", "C"); // 編譯 $smarty->display("temp01.html"); ?>
smarty可以賦值為數值,數字等值,可以是數組.
VIEW:
姓名: | {$name} |
年齡 | {$age} |
兵器 | {$weapon} |
姓名: | {$zf.name} |
年齡 | {$zf.age} |
兵器 | {$zf.weapon} |
姓名: | {$guanyu[0]} |
年齡 | {$guanyu[1]} |
兵器 | {$guanyu[2]} |
Controller
template_dir = "./templates"; $smarty->compile_dir = "./compile"; $user = array( "name" => "劉備", "age" => 28, "weapon" => "雙劍" ); // 賦值 $smarty->assign($user); $zf = array( "name" => "張飛", "age" => 25, "weapon" => "矛" ); $smarty->assign("zf", $zf); $guanyu = array("關羽", 25, "青龍"); $smarty->assign("guanyu", $guanyu); // 編譯 $smarty->display("liubei.html"); ?>
smarty模板標簽與css標簽防止沖突
如果smarty默認定界符 {} 與 css {} 沖突
可以使用以下二種方法解決
修改smarty默認定界符{{}}
也可以用{literal}{/literal}標簽,來告訴smarty,此處照常輸出,不用解析
// 配置smarty的左右定界符 $smarty->left_delimiter = "{{"; $smarty->right_delimiter = "}}";
smarty標簽變量的來源:
在模板中,{$title},則說明$title標簽在被assign賦過值。
smarty的標簽變量對應的來源,除了assign,還有那些?
PHP中assign分配變量
smarty的系統保留變量
從配置文件讀取到的配置變量
assign
// 引入 require("../smarty3/libs/Smarty.class.php"); // 實例化 $smarty = new Smarty(); // 配置 $smarty->template_dir = "./templates"; $smarty->compile_dir = "./compile"; // assign 賦值 $smarty->assign("name", "羅隱"); $smarty->assign("poem", "我未成名君未嫁,可能俱是不如人"); // 編譯 $smarty->display("shiju.html");
系統保留變量
系統保留變量,不用賦值,能夠自動獲取
{$smarty.get.id}
$smarty.開頭的標簽,當成系統變量來解析,如:$smarty.get.id解析成
還有以下幾個系統保留變量:
$smarty.post
$smarty.session
$smarty.cookies
常量如何顯示:
$smarty.const.常量名
{$smarty.const.HEI}
配置文件讀取配置變量
注意:
配置文件,一般以.conf做后綴
配置文件的寫法是:選項=值
配置smarty的config_dir,并把配置文件放在該目錄下.
配置文件:
site=pink tel="13164889431"
獲取配置文件中的變量:
// 引入: {config_load file="site.conf"} // 顯示append{$smarty.config.site}{#tel#}
連著往某個標簽賦值多個值,可以使用append
賦值:
$smarty->append("color", "tan"); // _tpl_vars["color"][] = "tan" $smarty->append("color", "pink"); // _tpl_vars["color"][] = "pink"
使用:
{$color[0]}
{$color[1]}
源碼:
$data->tpl_vars[ $tpl_var ]->value[] = $value;
把一個值壓入一個數組
smarty賦值時還能夠引用賦值
assignByRef("title", $title); // _tpl_vars["title"] = &title; // 引用賦值
這個功能在PHP5以后,意義不大,PHP5以后是寫時賦值
對象賦值和引用對象賦值
class Human { public $name = "zf"; public $age = 23; public function say() { return "HELLO WORLD"; } } $man = new Human(); $smarty->assign("man", $man);
顯示:
{$man->name}{$man->age}{$man->say()}
模板的作用:分離PHP代碼,讓代碼簡潔,所以模板中的標簽,應該盡量的只負責變量的輸出.不要負責太多的邏輯判斷,函數調用等.
簡化模板配置通過繼承來簡化模板配置
setTemplateDir("./templates"); // 模板文件位置 $this->setCompileDir("./compile"); // 編譯文件位置 $this->setConfigDir("./conf"); // 配置文件位置 } } ?>標簽數學運算
邏輯判斷{$age}{$age + 2}年紀差為:{$age - $diffAge}
IF標簽要成對
{if $price < 10000 }{$color}{else}TAN{/if}
{if $smarty.get.today == 0 || $smarty.get.today == 7}周日{elseif $smarty.get.today == 6}周六{else}工作日{/if}
在模板中使用邏輯判斷的思考:
從分工角度看:模板只負責輸出 ,不負責邏輯判斷。
為什么還需要有邏輯判斷? 在模板上進行邏輯判斷,可以極大的簡化工作.
for循環基本應用
賦值:
$smarty->assign("start", 1); $smarty->assign("end", 9);
顯示:
{for $i = $start to $end} {$i} {if $i % 3 == 0}
{/if} {/for}
1-100所有的奇數
{for $i=$start to 100} {if $i % 2 != 0 } {$i} {/if} {/for}
循環總次數$i@total,循環索引$i@iteration
foreach循環步長屬性 控制
{for $i=$start to 100 step 2} {if $i@first == $start} {$i} {elseif $i@last == $i@total} {$i} {else} {$i} {/if} {if $i@iteration % 3 == 0}
{/if} {/for}循環總次數:{$i@total}循環索引:$i@iteration循環的第一次:$i@first循環的最后一次:$i@last
foreach循環
典型場景,二維數組的循環
例如:新聞列表,會員列表,商品列表
賦值數據
assign($category); $smarty->display("foreach.html"); ?>
使用foreach:
商品欄目
序號 | 欄目名 | 欄目信息 |
{$g.cat_id} | {$g.cat_name} | {$g.intro} |
循環總次數$i@total,循環索引$i@iteration
商品欄目
序號 | 欄目名 | 欄目信息 |
{$g@iteration} | {$g.cat_name} | {$g.intro} |
變量調節器:在模板中,修改變量的顯示形式的一種功能.
變量調節器的本質是一個函數,這個函數,以標簽對應的變量值為參數,然后運算,把返回值,顯示在標簽處.
內置變量調節器:
capitalize [首字符大寫] count_characters [字符計數] cat [連接字符串] count_paragraphs [計算段數] count_sentences [計算句數] count_words [計算詞數] date_format [格式化日期] default [默認值] escape [編碼] indent [縮進] lower [小寫] nl2br [換行符替換成
] regex_replace [正則替換] replace [替換] spacify [插空] string_format [字符串格式化] strip [去除(多余空格)] strip_tags [去除html標簽] truncate [截取] upper [大寫] wordwrap [行寬約束]
使用變量調節器:
{foreach $goods as $key=>$g}{/foreach} {$g.goods_id} {$g.goods_name|truncate:15:"..."} {$g.shop_price} {$g.add_time|date_format:"%Y-%m-%d %H:%M:%S"}
調節器的功能,在PHP中也能實現,也可以在模板中進行。比較合適在模板中進行。
體現了業務與顯示的分離,盡量分離。
PHP就負責判斷條件,并取出數據來。
至于顯示的操作,應該盡量往"前"移(越接近用戶).
MySQL-->PHP-->模板-->JavaScript
合適在MySQL存儲原始數據,PHP中處理.
后臺的數據盡量“原始”,不要帶有樣式,格式。顯示的工作盡量靠前.
緩存,smarty重要概念。
緩存:把頁面內容保存在磁盤上,下次訪問相同頁面,直接返回保存內容。減輕了數據庫的壓力。
smarty緩存的用法:
開啟
配置緩存的生命周期
判斷是否緩存成功并是否從數據庫取出數據
輸出
// 開啟緩存 $smarty->caching = true; // 設置緩存生命周期 $smarty->cache_lifetime = 3600; // 緩存的文件目錄,用戶存儲緩存文件 $smarty->cache_dir = "./cache"; if ( !$smarty->isCached("cache.html") ) { // 判斷文件是否緩存 // 鏈接數據庫 $conn = mysql_connect("127.0.0.1", "root", ""); // 設置字符集 mysql_query("set names utf8", $conn); // 選擇數據庫 mysql_query("use boolshop", $conn); // 查詢數據 $sql = "select goods_id, goods_name, shop_price, add_time from goods limit 5"; $result = mysql_query($sql, $conn); $goods = array(); while ( $row = mysql_fetch_assoc($result) ) { $goods[] = $row; } // 關閉數據庫連接 mysql_close($conn); // 賦值 $smarty->assign("goods", $goods); echo "走了數據庫"; } $smarty->display("cache.html");局部緩存
smarty在頁面緩存的情況下,可以設置部分內容不緩存。頁面中有隨機廣告,時間,股票信息,不適宜緩存起來。
運行的時候,還是PHP代碼,沒有生成靜態數據。
控制局部不緩存:
在標簽中控制,該標簽不緩存。
// {$標簽 nocache}{$time|date_format:"%Y-%m-%d %H:%M:%S" nocache}
控制一段標簽不緩存
{nocache}{$time|date_format:"%Y-%m-%d %H:%M:%S"}
{$time|date_format:"%Y-%m-%d %H:%M:%S"}
{/nocache}
在PHP賦值時,就控制不緩存
$smarty->assign("time2", $time, true); // 第三個參數是 nocache,為true,說明不緩存
不緩存標簽,要保證總能從PHP處得到值.
調用函數
定義函數
function insert_welcome( $parm ) { return "WELCOME HELLO" . ", AGE:" . $parm["age"]; }
模板中使用:
單模版多緩存{insert name="welcome" age=21}
場景:為商品模板設置緩存,當時從url接收的goods_id,當緩存后,所有商品都一樣了,不合適。
能否為同一個模板,生成不同的緩存文件呢?
比如:根據ID的不同,來生成各個商品的緩存頁面。
可以使用:單模板多緩存,
原理:生成緩存的時候,可以再傳一個緩存ID。如果ID不同,則生成緩存文件不同。
// 編譯 $smarty->display("one_page.html", $goods_id);
一般的,哪些參數要影響頁面的內容,就需要把哪些參數,當成“緩存ID”。
例如:分頁:page=3, 欄目:cat_id=3
多個參數影響:
// 編譯 $one_page = $goods_id + $page; // 緩存ID,根據自定義規則計算 $smarty->display("one_page.html", $one_page); // 緩存判斷,也需要加緩存ID if ( !$smarty->isCached("one_page".html, $one_page) ) { }
模板緩存:
caching = true; // 設置緩存生命周期 $smarty->cache_lifetime = 10; // 緩存的文件目錄,用戶存儲緩存文件 $smarty->cache_dir = "./cache"; $goods_id = $_GET["goods_id"] + 0; if ( !$smarty->isCached("one_page.html", $goods_id) ) { // 鏈接數據庫 $conn = mysql_connect("127.0.0.1", "root", ""); // 設置字符集 mysql_query("set names utf8", $conn); // 選擇數據庫 mysql_query("use boolshop", $conn); // 查詢數據 $sql = "select goods_name, shop_price, goods_desc from goods where goods_id=" . $goods_id; $result = mysql_query($sql, $conn); $goods = mysql_fetch_assoc($result); // 關閉數據庫連接 mysql_close($conn); // 賦值 $smarty->assign($goods); } // 編譯 $smarty->display("one_page.html", $goods_id); ?>強制刪除緩存
簡單刪除緩存.
指定模板名,不指定緩存ID,則該模板對應的緩存都會被刪除.
可以通過緩存ID來控制,模板對應的指定緩存刪除掉.
clearCache("one_page.html", $goods_id); echo "刪除緩存成功"; ?>
出于調試目的,臨時不緩存文件
$smarty->force_cache = true; // 強迫文件不緩存數據對象
作用:數據分類,添加命名空間
不使用數據對象,所有數據都存儲在smarty對象中.(重名就覆蓋)
數據對象:把數據分類(不同類別的數據,重名不會覆蓋)
assign("nav", $nav_top); $smarty->assign("nav", $nav_footer); // 數據覆蓋 /** * smarty3引入一種新的概念,叫做數據對象。 * 數據對象,就是一個裝數據用的框。 * * 靠2個數據對象,把2個數據對象里,各賦值一個同名的`nav`,2個`nav`對象互不干擾 */ $smarty->display("news.html"); ?>
使用數據對象,命名空間
創建數據對象$smarty->createData();
數據掛載到該數據對象上.
$smarty->dispaly();聲明使用的數據
assign("nav", $nav_top); // $smarty->assign("nav", $nav_footer); /** * smarty3引入一種新的概念,叫做數據對象。 * 數據對象,就是一個裝數據用的框。 * * 靠2個數據對象,把2個數據對象里,各賦值一個同名的`nav`,2個`nav`對象互不干擾 */ // 創建一個數據對象 $hdata = $smarty->createData(); $fdata = $smarty->createData(); // 使用數據對象 $hdata->assign("nav", $nav_top); $fdata->assign("nav", $nav_footer); // display時,要聲明,這次使用,哪個數據對象。 $smarty->display("header.html", $hdata); $smarty->display("news.html"); $smarty->display("footer.html", $fdata); ?>對象注冊
場景:在模板中,smartty標簽中,允許調用對象的方法,如果方法是特殊方法,比如修改密碼等方法。(模板調用特殊方法)
使用對象注冊的方式來解決。
作用:允許調用的方法列表。
在View視圖中:
注冊對象的 變量:訪問方法{zf->name}. 注意不加$,方法后不加()
name; } public function modPass() { return "修改密碼成功"; } } $zf = new User(); // $smarty->assign("zf", $zf); // 對象注冊 $smarty->registerObject("zf", $zf, array("say")); // 第三個參數可以控制允許調用的方法. $smarty->display("objLogin.html"); ?>
模板繼承姓名:{zf->name}
年齡:{zf->age}
SAY:{zf->say}
{zf->modPass}
可以在父模板中,暫留{block name=""}{/block}
注意:
子模板第一句,先聲明繼承{extends file=""}
子模板的目的,只是填充父模板預留的block
父模板:
{block name="title"}父模板標題{/block} {block name="header"}{/block}
{block name="footer"}{/block}
子模板1:
{extends file="tplExteds.html"} {block name="title"}
子模板2:
{extends file="tplExted.html"} {block name="footer"}2016年最后二天{/block}變量調節器插件開發
調節器:
" . $string . ""; } ?>
在smarty源碼的目錄中,plugins, 開發。
文件命名modifier.函數名.php
定義的調節器的函數名:Smarty_modifier_modcolor
display與fetchdisplay() 可以看成 echo fetch();
fecth()僅僅計算出應輸出的結果,但是不輸出,只把結果返回。
一個PHP頁面如何知道本身的輸出結果: 使用緩沖區。
利用fetch靜態化緩沖區的理解:
fetch是如何知道當前頁面的輸出內容?
輸出到緩沖區,在PHP的最后,讀取緩沖區,就是本頁面的內容。
打開緩沖區:ob_start();
讀取緩沖區:ob_get_content();
清空緩沖區:ob_clean();
讀取并清空:ob_get_clenan();
靜態化:緩沖區+文件寫操作
模板引擎特點所有模板的共性:解析標簽,解析成PHP
標簽解析的分類:
最多的就是正則替換 。 例如:smarty2.X系列,quickskin
通過字符串函數來解析 例如:dede的模板類.
字符串解析
right_length = strlen($this->right_delimiter); } protected $tags = array(); // 裝載分析到的標簽 // 編譯 public function parse( $file ) { $cont = file_get_contents("./templates/" . $file); $offset = 0; // 截取第一個字符 "{" while ( $poss = strpos($cont, $this->left_delimiter, $offset) !== false ) { // 取最后字符 "}" $pose = strpos($cont, $this->right_delimiter, $poss); // 截取標簽 $this->tags[] = substr($cont, $poss, $pose-$poss+$this->right_length); $offset = $pose + $this->right_length; } return $this->tags; } } ?>
變量的存儲分類:
最多的是通過assign,把變量再次裝載到模板對象中。
如:smarty,thinkphp
只把模板解析出來,再包含模板
如:discuzd的模板,把模板解析后,只返回模板的路徑,再手動包含。(省略了assign過程,速度更快,顯示的粗糙暴力)
語言分類:
絕大部分PHP
C語言以擴展形式寫的模板引擎(Blitz)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/22213.html
閱讀 3448·2019-08-30 15:55
閱讀 2050·2019-08-30 15:44
閱讀 1453·2019-08-30 12:47
閱讀 740·2019-08-30 11:05
閱讀 1629·2019-08-30 10:54
閱讀 654·2019-08-29 16:07
閱讀 3566·2019-08-29 14:17
閱讀 2221·2019-08-23 18:31