Smarty自学笔记
文章目錄
- 1. Smarty介紹
- 1.1. 什么是Smarty
- 1.2. 為什么需要Smarty
- 1.3. Smarty的特點
- 1.4. Smarty大致流程圖
- 2. 自定義模板引擎
- 2.1. 思路講解
- 2.2. 完整代碼
- 3. 模板引擎的優化
- 4. 成熟模板引擎使用
- 4.1. 下載Smarty
- 4.2. 使用Smarty
- 5. 保留變量使用
- 6. 配置變量信息
- 6.1. 測試
- 6.2. 數字型的配置信息
- 6.3. 對于{}使用與css或js內容有沖突的解決
- 6.4. 覆蓋問題,設置段
- 7. 數組元素訪問及foreach遍歷
- 7.1. 數組元素訪問
- 7.2. 遍歷數組
- 8. 分支結構語句
- 9. 自定義函數
- 9.1. 模板自定義函數(了解即可)
- 9.2. PHP自定義函數
- 9.3. 按插件形式擴展的自定義函數
- 10. 內置函數
- 11. smarty表示復選框,下拉列表,單選按鈕的使用
- 12. 已有模板(純html)與Smarty結合
- 13. 布局繼承使用
- 14. 布局繼承擴展使用
- 15. 變量(修飾)調節器的使用
- 16. 緩存
- 16.1. 緩存介紹
- 16.2. 緩存設置及更新
1. Smarty介紹
1.1. 什么是Smarty
?Smarty是模板引擎技術之一。所謂的模板引擎就是為了使應用程序的業務邏輯(PHP代碼)和表示邏輯(HTML代碼)進行分離,從而達到程序員只關心程序的編寫,而美工人員進行頁面的設計的目的。
?模板:html+css。
?意思:可以使得"php代碼"與"html代碼"分離的技術都稱為模板引擎技術。
1.2. 為什么需要Smarty
?從團隊的角度出發,它可以提高工作效率,php程序員只負責編寫后臺的php代碼,獲取數據,將數據分配給前臺,美工人員或者說前端開發人員就只負責寫html,css,js這些,同時需要將后臺分配過來的數據進行展示,而模板引擎就是后臺和前臺之間的橋梁。它的出現就是讓二者的工作合二為一,因為前端人員可能不懂php代碼,而還要將后臺傳過來的數據進行展示,所以不可避免的要用到php代碼,比如,如下:
上圖php和html代碼混寫。$title是一個變量,它的值就是要從后臺獲取,此處是用php代碼來把它輸出出來,那么模板引擎smarty處于對前端人員的考慮,會有一個特殊符號代替php代碼,如上圖的<?php echo和結尾的;?>。
總歸一句話,后端和前端各司其職,互不干擾,而前端你不是不懂php嗎,沒關系,有smarty,你只需要記住smarty的特殊符號即可,smarty模板引擎自動會轉換。
1.3. Smarty的特點
1.4. Smarty大致流程圖
要點:PHP文件+tpl文件(html)+混合php+html文件(編譯文件)
2. 自定義模板引擎
2.1. 思路講解
?新建一個index.php文件
<?php$title="靜夜思";$content="床前明月光,疑是地上霜,舉頭望明月,低頭思故鄉"; ?> <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title></title> </head> <body> <div><?php echo $title; ?></div> <div><?php echo $content; ?></div> </body> </html>?上面php代碼和html混合在一起,不好維護,不利于團隊協作,按照規范,php代碼是php的,html是html的,也就是說,邏輯層和表現層要分離開來,程序員和美工各寫各的,寫完再整合。
?所以我們再新建一個index.html文件。也就是:
?那么index.php就是:
<?php$title="靜夜思";$content="床前明月光,疑是地上霜,舉頭望明月,低頭思故鄉";require “index.html”; ?>?很顯然,當我們再次訪問index.php的時候,就應該要把index.html包含進來,很簡單,就是require “index.html”; 在基礎語法已經學過了。
?但是,我們觀察index.html文件中,作為美工的角度去看,我是一個美工人員,并不懂php代碼。我的關注點在于頁面的美化上。所以說,你頁面上要輸出$title和$content是不是用到了PHP代碼的定界符和echo語句。所以,為了方便美工人員,我們就把變量前的<?php echo和變量后的; ?>去掉,去掉就剩了變量本事,但是,還是得要求美工人員,在變量前后要加上花括號。比如:{$title}。就表示要把$title這個變量輸出出來。不然就會以為你是一個字符串,就會原樣輸出。美工人員雖然不會PHP,但是簡單的花括號還是會的。對應了上圖表現層右邊的黑色字體的解釋。
?所以index.html就變成了:
?但是這樣去訪問,效果肯定不對,你還沒有對花括號進行處理呢,系統怎么會知道你那花括號就是要輸出PHP代碼的?所以它會原樣輸出就是{$title}和{$content}。那怎么才會輸出呢,肯定是要變回原來的echo啦!也就是說,要有一個工具,來對美工人員寫的html頁面中的花括號進行解析,解析成原來的風格。怎么一個解析發,首先,我們可以運用我們在基礎篇學的替換語法,讓{替換為<?php echo,再讓}替換為; ?>。這個工具就是模板引擎了,因為是自定義模板引擎,所以此處模板引擎是我們自己寫,來感受一下。
?最后生成出來的我們單獨給它放到一個文件中,后綴就是.html.php。起名比如idx.html.php。就可以看出來它是一個混編文件。上面的index.html是模板文件。中間的模板引擎也得有一個具體的文件來完成它的替換功能,它是一個類,起名為MiniSmarty.class.php,這個類是一個工具,是共用的。
?注意idx.html.php是可以自動創建的,寫好了功能類,接下來就是要在index.php中去調用類中的函數,完成替換功能。
<?php$title="靜夜思";$content="床前明月光,疑是地上霜,舉頭望明月,低頭思故鄉";//下面這樣直接require包含index.html是不行的,因為它的花括號并沒有被處理,所以要把它注釋掉//require "index.html";//得把index.html里面的內容換成真正的php的內容。//所以,要引入MiniSmarty.class.php,它是一個類,所以我們要new它require "MiniSmarty.class.php";//類中有個替換功能,要想調用,必須實例化。$smarty = new MiniSmarty();//調用類中的compile函數,完成替換功能,那么傳進去的參肯定是你要替換的那個頁面。$smarty->compile("index.html"); ?>
?也就是說,美工寫的模板頁面,最終會被模板引擎解釋成上面的樣子,就是idx.html.php,最終展示在瀏覽器的就是idx.html.php。但是結果卻是報變量未定義,如下圖:
?為什么呢?因為它是局部變量,它是不是在函數里,它能不能訪問到函數外部的變量?肯定不能。現在是解決上面變量未定義的問題:第一反應,就是在函數里加global,但很明顯,不行。哪解決辦法是什么?可以把模板引擎內部使用的變量信息都聲明為該"模板類"的屬性信息,這樣在類的內部可以正常使用本身的屬性信息。所以,在類里部加幾句代碼,如下:
?那么,在index.php中,就要調用assign方法,如下:
$smarty -> assign("title",$title); $smarty -> assign("content",$content);?類中的替換也要有所改變:
$cont = str_replace('{$', '<?php echo $this->tpl_var["', $cont); $cont = str_replace('}', '"]; ?>', $cont);2.2. 完整代碼
index.php:
<?php$title="靜夜思";$content="床前明月光,疑是地上霜,舉頭望明月,低頭思故鄉";//下面這樣直接require包含index.html是不行的,因為它的花括號并沒有被處理,所以要把它注釋掉//require "index.html";//得把index.html里面的內容換成真正的php的內容。//所以,要引入MiniSmarty.class.php,它是一個類,所以我們要new它require "MiniSmarty.class.php";//類中有個替換功能,要想調用,必須實例化。$smarty = new MiniSmarty();$smarty -> assign("title",$title);$smarty -> assign("content",$content);//調用類中的compile函數,完成替換功能,那么傳進去的參肯定是你要替換的那個頁面。$smarty->compile("index.html"); ?>index.html:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title></title> </head> <body> <div>{$title}</div> <div>{$content}</div> </body> </html>MiniSmarty.class.php:
<?php //模板引擎類 class MiniSmarty{//給該類聲明屬性,用于存儲外部的變量信息public $tpl_var = array();//把外部變量設置為類內部屬性的一部分function assign($k,$v){$this->tpl_var[$k]=$v;}//編譯模板文件(將花括號替換為php標記)function compile($tpl){//獲得模板文件內部具體的模板內容$cont = file_get_contents($tpl);//獲取index.html的內容,結果是//echo $cont;//效果如下/*{$title}{$content}*///是不是用file_get_contents把html的內容讀取出來,用字符串的形式輸出,展示在瀏覽器上,就形成了上面的效果。//替換:“{” --> “< ?php echo” “}“ --> ”? >”$cont = str_replace('{$', '<?php echo $this->tpl_var["', $cont);$cont = str_replace('}', '"]; ?>', $cont);//echo $cont;//頁面沒有任何顯示,右擊打開源代碼,發現已經替換內容。為什么頁面沒內容呢?//是因為你echo 出來的$cont是一個字符串//把它輸出來的信息放到一個文件(php+html的混編內容)即可,然后require進來file_put_contents("idx.html.php",$cont);//如果文件沒有,自動創建//再引入混編文件require "idx.html.php";} }3. 模板引擎的優化
1.混編文件一旦生成好,不要反復生成,直接引入即可。解決思路就是給每個應用都生成一個唯一的混編文件,執行之前先判斷是否存在,如果存在就直接引入,否則再生成。
2.但是缺陷也來了,如果我index.html增加了一個變量呢?你index.php再訪問它就訪問到原來的index.html.php文件,而不是新的php文件,也就是說,模板文件如果有修改的話,混編文件就得重新生成。所以,這要在怎么判斷?
?答案是通過時間來判斷,比如我們是先有模板文件index.html再有index.html.php混編文件,所以混編文件的時間是大于模板文件的時間,如果有一天模板文件的時間大于了混編文件的時間,就說明混編文件不是最新的,模板文件產生了修改,這時候就要重新生成混編文件了。如下:
3.如圖:
是不是發現這樣存放的話像混編文件和模板文件這些都混雜在一起,不好看,應該建立一個文件夾,一個文件夾專門放模板文件,一個文件夾專門放混編文件,這樣分類存儲,即美觀,也好管理。新建一個文件夾叫view,專門存放模板文件,再新建一個文件夾叫view_c,專門存放混編文件。
4. 現在上面已經很完美了,功能也實現了,不過上面compile,譯為編譯,有點底層,我們可以再寫一個方法叫display,display翻譯叫顯示,顯示嘛,更你體現表明的意思,用來展現模板,容易理解,所以:
相應的,index.php調用的方法名從compile要改為display。
總結:
注意,最后交給瀏覽器的是混編文件的內容。并且模板文件不允許出現php代碼,只允許出現模板標記,比如花括號,否則將原樣輸出,php代碼不會被解析。
4. 成熟模板引擎使用
4.1. 下載Smarty
打開該官網 https://www.smarty.net/ :如圖
這里我就選擇3.1.34版本的。就是 smarty-3.1.34.zip。解壓該目錄:
demo文件夾是例子。libs文件夾是資源庫。最核心,最主要的文件都在這里面了。點進去:
當中有Smarty.class.php文件,說明它是類,類似于上面我們自己寫的Smarty模板引擎類。plugins是插件的意思,表示里面存放這一系列的插件,我們可以在里面擴展自己的插件。sysplugins是系統核心的插件文件。它里面有assign啊,for啊,foreach啊,if啊等等這些,assign是不是前面自己寫的設置屬性信息?有了這些的支持,我們才可以在模板中使用。
4.2. 使用Smarty
?使用Smarty得把本身主要的類文件和它相關輔助的文件都得復制到我們的工作目錄,復制libs文件夾就可以了。好接下來,我們新建一個index.php。程序員開始工作了。首先,新建好index.php文件,與libs文件夾平級,接下來就打開新建好的index.php文件,引入模板引擎類了,模板引擎類就在libs文件夾里。如下:
<?php //引入官方的模板引擎類 include "./libs/Smarty.class.php";?引入來之后,就是對類進行實例化,調用方法:
<?php //引入官方的模板引擎類 include "./libs/Smarty.class.php"; //實例化對象 $smarty = new Smarty; //展示模板,調用display,是不是跟上面寫迷你版的smarty是一樣的。 $smarty->display('index.html');?好,接下來,就是又美工人員開始寫index.html文件了,在寫自定義的Smarty,我們把html文件放在一個叫做view的文件夾,混編文件放在一個叫做view_c的文件夾,那么官方的Smarty是不是這樣呢?這就要打開官方的Smarty類了,因為我們知道,在寫迷你版的時候,定義文件名是不是在自己寫的類定義的。所以,打開,ctrl+F查找templates或者templates_c。
?所以,我們要創建一個文件夾,名叫templates,存放模板文件,一個叫templates_c,存放混編文件。最終的效果如下:
?當然了,上面的libs文件夾你可以改名為smarty文件夾,就是把libs改名為smarty。
簡單的測試Smarty
?好,我們在index.html的body中寫上一段代碼:<h2>哈哈哈哈哈</h2>,那么,當我們運行index.php文件的時候,能不能把官方給我們的效果展示出來?
?這樣是不是成功啦!!,我們還需要自己寫模板引擎類嗎,是不是不需要了,別人已經寫好了,我們拿來用就行,我們程序員就只需要關注與我們的業務邏輯。
?然后它是不是給我們生成了一個混編文件呢?
?確實生成了。
傳參測試
index.php:
<?php include "./libs/Smarty.class.php"; $smarty = new Smarty; $smarty->assign("name","小霆"); $smarty->assign("addr","廣州市白云區"); $smarty->display('index.html');index.html:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body>姓名: {$name}<br/>地址: {$addr}<br/> </body> </html>效果如下:
很明顯,傳參也是對的,并且可看出Smarty也是用花括號。可以打開官方的模板引擎類,如下圖:
屬性$left_delimiter是可以修改的,也就是這個類里面的所以都可以修改,但是不推薦,核心類的東西最好不要修改。
5. 保留變量使用
?在上面我們用assign方法來傳遞變量信息,這只是其中的一種方式,總有三種,接下來來講另外兩種。這節講其中一種,還有一種在第6節。
?對PHP里邊的超級全局數組變量信息的使用,例如$_GET…常量…等等這些。有這么一個請求:XXX/index.php?sex=男。我們發現他是get請求,get的請求,我們是不是要在index.html用$_GET來接收?我們說過了,模板文件是不允許出現php代碼的,只允許出現模板標記花括號,所以,直接寫php代碼是不行的。還有一個方法,就是在index.php獲取到sex的值以assign的值賦值給一個變量。比如:
這種雖然可以,但是不行,它還要賦值給一個變量,我們直接用不行嗎?
這時候就用到Smarty的保留變量了,它就是$smarty,所以,我們在自己起變量名的時候,不能叫做smarty,它是一個關鍵字,不然沖突了。怎么用,如下:
常量也一樣,不受作用域的限制,在哪都可以訪問,不需要assign,要assign都是那些受作用域限制的變量。如下:
{$smarty.const.HOST} //const表示常量,HOST是自己定義的常量名常量我們只需要在index.php定義好即可。
相應的,get可以替換成post,session,cookies,request,server…
當然了,還可以表示時間戳,如下:
還有很多,如下:
{$smarty.config} //獲取配置信息 {$smarty.section} //跟循環有關 {$smarty.template} //獲得當前模板的名稱,如果你的模板名是index.html,那獲得的就是index.html {$smarty.current_dir} //返回當前模板的目錄名稱,也就是templates {$smarty.version} //模板引擎的版本 {$smarty.ldelim} //獲取模板引擎的左定界符 { {$smarty.rdelim} //獲取模板引擎的右定界符 }6. 配置變量信息
?網站上有一些比較簡單的變量信息,美工人員可以自行定義并調用,這樣可以脫離程序員的依賴,工作比較有主動權。比如美工人員定義了一個變量,你php文件中并沒有去assign這個變量,是不是模板中的變量就得不到解析呢?當然,它適用于一些簡單的信息。
?配置變量是不需要PHP程序來提供的。
6.1. 測試
首先,配置信息對應的配置文件要創建好。
所以,我們要建立一個文件夾叫做configs,里面存放配置信息。configs文件夾與libs文件夾平級。然后在configs文件夾下創建一個配置文件,名字隨便,比如叫size.conf,后綴是.conf,conf就表示配置的意思。
打開創建好的size.conf文件,編輯,如下:。
NETWORK=互聯網出版許可證粵002號 POLICE=京公網安備 11000002000088號在模板里面使用上面的兩個配置變量,格式:{#變量名稱#},那么在index.html中:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body>{#NETWORK#}<br>{#POLICE#} </body> </html>引入size.conf,如下圖:
{config_load file="site.conf"}<!-- 不需要用路徑來表示 --><!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body>{#NETWORK#}<br>{#POLICE#}</body></html>最終測試,是不是引入成功了!!!如下圖:
還有一點,像上面,我們可以用保留變量來使用,記不記得{$smarty.config},沒錯,如下代碼:
上面兩個的效果是一樣的。
6.2. 數字型的配置信息
當我們在size.conf里面增加這么一句信息,如下:
MONEY=123343242424324324執行效果如下:
是不是發現了不一樣啊,根本跟我們在配置文件配置的不一樣,這是為什么呢?上面瀏覽器展示的數字其實是PHP所能表示的整形的最大數字。不信,用下面代碼測試一下,看看是不是一樣的。
答案就是一樣的。我們在配置文件中定義的數字是不是被它們看出數字了,我們定義的數字已經超出PHP所能表示的最大數字。如果我們想表示它,就得加上一對引號,表示它是字符串。
MONEY="123343242424324324"6.3. 對于{}使用與css或js內容有沖突的解決
把smarty的標記{}更改為其他的標記。
給{}標記的開始和結束添加空格。
如果不想加空格,可以這樣,如下代碼:
{literal} <style type="text/css">div{color:yellow;width:500px;height:400px;background-color:lightblue;} </style> {/literal}也就是說,被{literal}包含的標記是不會被smarty解析的。這樣的可讀性更好。
6.4. 覆蓋問題,設置段
site.conf:
CLR=red WD=300px HT=200px BG=pinkCLR=blue WD=400px HT=300px BG=lightblueindex.html:
{config_load file="site.conf"}<!-- 不需要用路徑來表示 --> <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> <style type="text/css">div{ color:{#CLR#};width:{#WD#};height:{#HT#};background-color:{#BG#}; }</style> </head> <body><div></div> </body> </html>最終的效果是不是我們在配置文件中最后一次定義的效果,比如上面CLR,blue是不是把red給覆蓋掉了,有這么一個需求,就是可以根據自己的喜好隨意切換顏色,就是切換模式,像上面配置文件就有兩個模式了,哪要怎么樣才能體現兩個模式呢?如下:
[year] CLR=red WD=300px HT=200px BG=pink[yuandan] CLR=blue WD=400px HT=300px BG=lightblue是不是把上面分成了兩個段啊。比如我喜歡year段的,哪就要在index.html進行設置,如下:
{config_load file="site.conf" section="year"}沒錯,就是section="year"。這樣就ok啦。
注意:如果把section給去掉了,哪它什么都不會給你顯示。你設置段,就得使用段。
7. 數組元素訪問及foreach遍歷
7.1. 數組元素訪問
格式如下:
//smarty對數組元素的訪問 {$數組[下標]} {$數組.下標}不管是索引數組還是關聯數組都可以通過上面兩種方式訪問。
對index.php進行編輯:
再對index.html進行編輯:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body>{$fruit[2]} <!--orange-->{$fruit.3} {*watermelon*} <!--這種格式{* *}屬于注釋 --> </body> </html>7.2. 遍歷數組
foreach
格式如下:
{foreach 數組 as $k=>$v} 或 {foreach 數組 as $v}做具體數組遍歷 {foreachelse}數組沒有任何元素信息 {/foreach}跟php的基礎語法中的foreach的區別在于foreach后面是括號括起來的。這里可以省略。if也是一樣的道理。
那么index.html如下:
關聯數組也是如此,但是如果遍歷的關聯數組前面要有序號怎么辦?
值變量@iteration-->從1開始的序號信息 值變量@index-->從0開始的序號信息那么代碼如下:
{foreach $fruit as $k => $v}{$v@iteration}--{$k}--{$v}<br/> {foreachelse}數組沒有任何元素 {/foreach}最終效果:
1--0--banana 2--1--apple 3--2--orange 4--3--watermelon除了表示序號的,還有:
值變量@first-->判斷第一個元素,返回boolean 值變量@last-->判斷最后第一個元素,返回boolean 值變量@total-->獲得數組元素長度,可以放在foreach外面 值變量@show-->判斷當前數組是否有元素遍歷出來,返回boolean,比如像空數組,就算遍歷也沒有元素出來,就是false,false就是0。section
section遍歷只能遍歷索引數組,不能遍歷關聯數組。
格式如下:
index.html如下:
{section name=v loop=$fruit}{$fruit[v]} {/section}8. 分支結構語句
單路分支
{if 條件}分支邏輯 {/if}雙路分支
{if 條件} {else} {/if}多路分支
{if 條件} {elseif 條件} {elseif 條件} {else} {/if}9. 自定義函數
9.1. 模板自定義函數(了解即可)
所謂模板自定義函數:是smarty模板提供給你的函數。格式: {函數名 屬性名=屬性值}
assign:assign上面已經提到過,我們都不默生,它是模板引擎類當中的一個函數,assign它的作用就是用于在模板被執行時為模板變量賦值。我們在模板文件中index.html或者后綴是.tpl都沒錯,因為它是模板,我們在模板里有這么一句話:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body>{assign} {*報錯*}</body></html>上面直接執行index.php是報錯的,為什么會報錯,因為它缺少兩個屬性,如下:
<html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body>{assign var=name value=Lee}</body></html>上面var表示一個變量,value表示變量的值,這樣雖然不會報錯,就是沒效果,其實在模板中這樣寫,就相當于我們在index.php中這樣寫:
$smarty->assign("name","Lee");所以知道模板頁面該怎么把變量輸出出來了吧,如下:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body>{assign var=name value=Lee} {*值加上雙引號和不加雙引號都可以*}{$name}</body></html>這樣就正確顯示。
counter:用于輸出一個計數的過程 ,如圖:
最終結果是1 2 7 8 9 10
{counter start=3 skip=2} {*表示往后都是從3開始,步長為2*} {counter} {counter} {counter} {counter} {counter}最終結果是3 5 7 9 11 13
{counter start=3 skip=2 direction=down} {*表示往后都是從3開始,步長為2,down表示遞減,up就是遞增*} {counter} {counter} {counter} {counter} {counter}最終結果是3 1 -1 -3 -5 -7
{counter start=3 skip=2 direction=down} {counter} {counter print=false} {*不輸出*} {counter} {counter} {counter}最終結果是3 1 -3 -5 -7
{counter assign=c} {*輸出值將被賦給模板變量的名稱*} {$c}cycle:用于交替輪換一組數據,比如背景色輪替交換。
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><p style="background:{cycle values='red,green'};">1</p><p style="background:{cycle values='red,green'};">2</p><p style="background:{cycle values='red,green'};">3</p><p style="background:{cycle values='red,green'};">4</p><p style="background:{cycle values='red,green'};">5</p>{*上面的操作要放在.tpl后綴的文件上,如果放在.html文件,上述語句會編譯報錯*}</body></html>效果如下:/font>
debug
<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body>{debug}</body> </html>eval:eval可以顯示普通變量和配置變量。
<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body>{eval var=$name} {*輸出變量$name,跟{$name}是一樣的*}{eval var=#NETWORK#} {*輸出配置變量,跟{#NETWORK#}是一樣的*}</body> </html>跟assign結合:
{eval var=#NETWORK# assign=c} {$c} {*或者{eval var=$c}*}fetch:fetch可以引入其他文件的源代碼。
{fetch file="http://www.baidu.com"}說到fetch,要知道它跟display的區別,如下代碼:
$smarty->display(index.tpl);就相當于:
$html=$smarty->fetch(index.tpl); echo $html;fetch僅是計算出應輸出的結果,但是不輸出,只把結果返回。
html_image:
{html_image file="xxx" href="xxx" border="xxx"}html_table:顯示表格
index.php
index.tpl
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> {html_table loop=$table } </body> </html>math:用于計算
index.php
index.tpl
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> {math equation="$x+$y"} {*或者可以這么寫{math equation=x+y x=$x y=$y}*} <br> {$x+$y} {*這也一樣可以,跟上面比多此一舉*} </body> </html>mailto:發送郵件。
{mailto address="xxx.qq.com" text="小霆"}html_checkboxes: 請看第11章節。
html_select_date:可以顯示日期的下拉列表。
{html_select_date month_format='%m'} {*月份默認是英文的,所以要格式化*}
年份不對,不能選擇,這么才能讓它選擇呢?如下代碼:
然后怎么把年放到前面去呢?
{html_select_date month_format='%m' start_year="1999" end_year="2060" field_order="YMD"}注意觀察field_order,默認是MDY,YMD就是年月日。
9.2. PHP自定義函數
函數注冊—單標簽 類似html的<br> br標簽不是閉合標簽
?就是你在php文件里自己創建了一個函數,然后通過smarty的函數注冊功能將你的函數注冊到模板中去,而模板直接寫上函數名,和它的屬性,就可以調用這個函數。
?假如在模板中有這么一句話:
也就是說,有個函數叫info,這是smarty沒有的函數,那我們要在index.php哪里進行創建。
在模板里注冊一個函數,并且可以傳參,可以使用register_function(‘模板函數名’,‘函數名’)
接下來測試一下:執行index.php,就是你好,說明成功。現在是接收數據,有3個數據,用數組形式。
function fn_info($a){print_r ($a); //Array ( [age] => 28 [height] => 178 [blood] => A ) return "你的年齡是:{$a['age']}歲,身高:{$a['height']},血型:{$a['blood']}"; }塊注冊—雙標簽(閉合標簽)
我們上面的例子{info}是不是一個單標簽,如果是{info}內容{/info},那么就是雙標簽,那要怎么實現呢?注意了這時候注冊的不是函數,而是塊。
index.html:
index.php:
<?php include "./libs/Smarty.class.php"; $smarty = new Smarty; function fn_info($a){return "你的年齡是:{$a['age']}歲,身高:{$a['height']},血型:{$a['blood']}"; } $smarty->registerPlugin('block','info','fn_info'); $smarty->display('index.html');注意第一個參數是block,是塊的意思,區別于上面的function。
看結果:
可是為什么ssss并沒有輸出出來呢?這就是自定義函數的第二個參數了,如下:
注意$b,$b就是表示內容ssss。
9.3. 按插件形式擴展的自定義函數
就是在libs文件夾下的plugins文件夾下新建一個文件,那這個文件就是我們自定義的插件。
所以:
這時候我們php就剩下這些了:
index.html頁面:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> {info age=28 height=178 blood=A} </body> </html>效果一樣可以出來。
10. 內置函數
什么是內置函數,內置函數是模板引擎的一部分,用于實現模板中一些流程控制等結構的語句。內置函數和自定義函數的區別是:內置函數不能修改,也不能創建和內置函數同名的自定義函數。
{php}內容{/php}表示可以在模板中使用php代碼。但這違背了業務和模板分離的原則,所以不推薦使用。
{include file=‘xxx.tpl’} 引入tpl模板文件
{config_load file=“xxx”}
{literal}xxx{/literal}
{if}…{elseif}…{else}…{/if}
{strip}…{/strip} 將代碼中的空格壓縮掉
{ldelim}…{rdelim} 左分隔符{和右分隔符}
{capture}…{/capture} 將包含的數據保存起來,指定輸出
{capture}我失蹤了~~ {/capture}這樣是看不到效果的。要想看到效果,如下:
{capture name="me"}我失蹤了~~ {/capture} {$smarty.capture.me}{insert} 和自定義函數類型,但有不被緩存的特點。
index.php:
{insert} 和自定義函數類型,但有不被緩存的特點。
index.html:
{foreach} 如下代碼:
index.php
index.html
{foreach from=$arr1 item=value key=a}{$a}:{$value} {foreachelse}沒有任何數據 {/foreach}可以給它一個名字name:
{foreach from=$arr1 item=value key=a name=abc}{$smarty.foreach.abc.iteration}:{$a}:{$value} {foreachelse}沒有任何數據 {/foreach} {$smarty.foreach.abc.total} {*total表示有多少條數據*}11. smarty表示復選框,下拉列表,單選按鈕的使用
復選框
index.php如下:
<?php include "./libs/Smarty.class.php"; $smarty = new Smarty;$smarty->assign("outval",array("a"=>'乒乓球',"b"=>'籃球',"c"=>'橄欖球',"d"=>'足球')); $smarty->display('index.html');index.html如下:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body><h2>復選框應用</h2>愛好:<!-- <input type="checkbox" name="hobby[]" value="a">乒乓球<br><input type="checkbox" name="hobby[]" value="b">籃球<br><input type="checkbox" name="hobby[]" value="c">橄欖球<br><input type="checkbox" name="hobby[]" value="d">足球-->{html_checkboxes name="hobby" options=$outval} </body> </html>注意看smarty提供的html_checkboxes,它當中的options表示多選框的值-顯示的數組。它集合了values和output,output就是顯示外面的數據,就是瀏覽器看到的數據。你也可以單獨使用values和output,是數組類型。
最終效果:
如果想讓它一上來就自動選擇某個值:
在index.php中
在index.html中
{html_checkboxes name="hobby" options=$outval selected=$seled}還有分割符號:
{html_checkboxes name="hobby" options=$outval separator="<br/>"}用換行來分割。
還有給<label>和<input>設置ID屬性:
下拉列表
index.php:
$smarty->assign("area",array(1=>'廣州',2=>'揭陽',3=>'深圳',4=>'上海'));index.html:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body><h2>下拉列表應用</h2>城市:<!-- <select name="city"><option value="1">廣州</option><option value="2">揭陽</option><option value="3">深圳</option><option value="4">上海</option></select>-->{html_options name="city" options=$area} </body> </html>如果一上來就讓某個選中,跟上面講復選框是一樣的。當然了,我們的下拉框是不是可以多項選中,如果要多項選中,則:
{html_options name="city" options=$area selected=$seled multiple="multiple"} //這時候$seled應該是數組單選按鈕
單選按鈕就是{html_radios},操作跟上面是一樣的,什么name啊,options啊,selected啊,分隔符啊,都是一樣的。
12. 已有模板(純html)與Smarty結合
?純html所要用到的靜態資源,比如css,js,img都要放到一個目錄里,改目錄起名為public,在public目錄下有3個目錄,分別是存放css文件的目錄,一個存放js文件的目錄,還有一個存放img的目錄。
?注意html引入靜態資源時的路徑要以入口文件,入口文件應該是php,因為是由php來調用html的,通過上面的學習可知。所以路徑的引入要以php,也就是入口文件為基準。但如果css文件本身有引入img圖片,其路徑相對css文件設置。
?完了之后,接下來就是利用上面所學的知識,在入口php文件獲得變量信息用于模板顯示。
13. 布局繼承使用
?在一個網站中多個頁面他們頭部可以是一樣的,底部也可能是一樣的,那怎么多一樣的維護起來也不是很方便,我們應該只維護一份,在這一份當中如果有個字變了,那么其它多個頁面都會改變,這就要用到布局繼承的知識了。
?為了使得許多頁面的共同頭部,腳部開發/維護方便,我們制作一個布局頁面,其它具體業務頁面來填充該"布局"頁面。
?在templates文件夾下創建一個layout.html頁面,它是一個布局頁面,如下:
?然后新建兩個頁面,一個是index.html,一個是登陸頁面login.html,在這兩個頁面當中都有相同的頭部和底部,只是中間的業務邏輯不同罷了,而頭部和底部我們是不是在layout.html中就已經定義好了,所以,在這兩個頁面,我們只需要寫中間部分的業務邏輯即可,頭部那些用一個標簽引進來即可。所以:
?index.html:
?index.php就不用說了,執行index.php,效果展示如下:
同理,login.html也是如此,如下代碼:
效果展示:
14. 布局繼承擴展使用
?上面是按照上中下布局的,現在如果上中下不變,但是中間部分還得再分,什么意思,如下兩副圖:
?上面兩幅圖就是兩個頁面,兩個html,頭部和底部不說,中間部分左邊的目錄其實是不變的,只是目錄的右邊在隨著左邊的目錄變化,那么左邊目錄是不是也可以抽取出來,放在布局頁里。
?像這種來布局上中下的布局就不合適了,最好設計為上左右下布局。
?當然,你來繼承的時候,不僅僅是上左右下的布局,也可以是上中下的布局。就是說,萬一某個頁面它中間部分沒有左邊的列表信息呢。如下圖:
?新建layout.html布局頁面:
注意:
新建一個注冊頁面register.html:
注冊頁面是一個典型的上中下的效果,它中間部分沒有左邊的信息欄,即使這樣,它一樣可以繼承上左右下的布局頁:
效果如下:
好,接下來是實現上左右下的效果,我們在上面布局頁面的代碼中,有一個我的訂單,那么我們就新建一個訂單頁面myorder.html:
效果如下:
在templates文件夾中為了避免模板頁面和布局頁面混亂,會專門給布局頁面創一個文件夾,就在templates里創,叫common。
15. 變量(修飾)調節器的使用
?在模板中獲得的變量信息,有可能不是我們需要的信息(例如時間戳,不好讀,需要將其轉換為格式化信息),需要調用其它函數對該信息進行第二次,第三次等修飾才會變成我們想要的結果,smarty本身不支持我們在模板中使用php函數,其把函數封裝了一下,封裝的函數就是smarty的變量調節器。
比如date_format就是變量調節器,它是對php函數date的封裝, 在學習php基本語法時,是不是date("Y-m-d:i:s",時間戳); 再比如upper也是變量調節器,upper是不是轉換為大寫,首先格式是{變量|變量調節器} 所以{$title|upper}的意思就是把$title所輸出的東西轉換為大寫,upper就是對strtoupper()函數的封裝。 然后上面格式化就是:{$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}總結一下格式,就是:
{變量名稱|修飾變量的方法名:參數:…}
變量和修飾變量的之間用"|“隔開。如果有多個參數,則使用”:"隔開。
官方文檔:https://www.smarty.net/docs/zh_CN/language.modifiers.tpl
date_format支持格式:
%a - 當前區域星期幾的簡寫
%A - 當前區域星期幾的全稱
%b - 當前區域月份的簡寫
%B - 當前區域月份的全稱
%c - 當前區域首選的日期時間表達
%C - 世紀值(年份除以 100 后取整,范圍從 00 到 99)
%d - 月份中的第幾天,十進制數字(范圍從 01 到 31)
%D - 和 %m/%d/%y 一樣
%e - 月份中的第幾天,十進制數字,一位的數字前會加上一個空格(范圍從 ’ 1’ 到 ‘31’)
%g - 和 %G 一樣,但是沒有世紀
%G - 4 位數的年份
%h - 和 %b 一樣
%H - 24 小時制的十進制小時數(范圍從 00 到 23)
%I - 12 小時制的十進制小時數(范圍從 00 到 12)
%j - 年份中的第幾天,十進制數(范圍從 001 到 366)
%k - 小時,24 小時格式,沒有前導零
%l - 小時,12 小時格式,沒有前導零
%m - 十進制月份(范圍從 01 到 12)
%M - 十進制分鐘數
%n - 換行符
%p - 根據給定的時間值為 am' 或pm’,或者當前區域設置中的相應字符串
%r - 用 a.m. 和 p.m. 符號的時間
%R - 24 小時符號的時間
%S - 十進制秒數
%t - 制表符
%T - 當前時間,和 %H:%M:%S 一樣
%u - 星期幾的十進制數表達 [1,7],1 表示星期一
%U - 本年的第幾周,從第一周的第一個星期天作為第一天開始
%V - 本年第幾周的 ISO 8601:1988 格式,范圍從 01 到 53,第 1 周是本年第一個至少還有 4 天的星期,星期一作為每周的第一天。(用 %G 或者 %g 作為指定時間戳相應周數的年份組成。)
%w - 星期中的第幾天,星期天為 0
%W - 本年的第幾周數,從第一周的第一個星期一作為第一天開始
%x - 當前區域首選的時間表示法,不包括時間
%X - 當前區域首選的時間表示法,不包括日期
%y - 沒有世紀數的十進制年份(范圍從 00 到 99)
%Y - 包括世紀數的十進制年份
%Z - 時區名或縮寫
%% - 文字上的 `%’ 字符
?再講一個default,默認值,就是如果模板有一個變量是未定義的,就可以使用default,不然就會報這個變量未定義。
{$aa|default:"bb"}?還有一個,如下:
//在index.php中 $smarty->assign('baidu',"<a>百度一下</a>");如果你是這樣{$baidu}獲取,只能獲取百度一下這四個字,如下:
但是如果你用一個變量調節器修飾一下,就是escape
{$baidu|escape} {*轉義,轉換html標簽為符號實體*}效果如下:
縮進符號indent,直接看代碼:
效果如下:
還有替換replace:
還有去除html標簽的strip_tags。截取的truncate:
{$talk|truncate:20} {*截取20個字符,一個英文一個字符*}變量調節器可以有多個,嵌套一起使用,多個用|分隔即可。?
上面只是籠統的說一下,詳細還得去看官方文檔。
16. 緩存
16.1. 緩存介紹
緩存類型有兩種:頁面緩存和數據緩存。
頁面緩存:php代碼被php模塊解釋完畢生成的靜態內容,放到一個文件里邊,該文件稱為緩存文件。
數據緩存:把mysql的數據讀取出來放到速度更快的介質上(內存)操作。
smarty調用display方法獲得模板內容,首先:判斷是否有靜態緩存文件,如果有直接獲取并返回給用戶,其次:沒有靜態緩存文件,判斷是否已經存在對應混編文件,如果有直接走,如果沒有對應的混編文件,則按部就班,每一個過程都會執行。
16.2. 緩存設置及更新
開啟緩存
編輯index.php
<?php include "./libs/Smarty.class.php"; $smarty = new Smarty; $smarty->assign('animal',array('dog','cat','tiger')); $smarty->display('index.html');編輯index.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body><h2>緩存制作</h2><ul>{foreach $animal as $k => $v}<li>{$v}</li>{/foreach}</ul> </body> </html>?下一次訪問就是直接拿混編文件了,并不會被模板引擎進行替換操作,性能更高,但是,我們還可以把混編文件存變成一個純html的頁面緩存起來,下次就直接拿緩存好的html頁面,性能更高,不然,你直接拿混編文件,因為混編文件里面有php代碼,所以要給php進行解析,在返回個瀏覽器,是不是經歷了一個給php解析的操作,如果我們把php解析好的,最終給瀏覽器的頁面緩存起來,那么性能上是不是就更優了,那這要怎么做?
?想設置緩存,就在php頁面里對$smarty對象進行操作,如下:
效果如下:
?開啟緩存之后是不是會在項目下新建一個文件夾,叫cache,里面就是純html代碼,瀏覽器可以直接解析,不需要php解析,比起混編文件夾性能更加提高。注意,它是頁面緩存。這時候你再訪問,它就是直接拿緩存文件了。
?因為你現在是直接拿緩存文件了,那如果你在index.php中assign一些新數據,修改了一些內容,那么你再去訪問緩存文件就不合適了,就要讓緩存文件實時更新,這又怎么辦?
緩存更新
刪除對應的緩存文件,系統會更新,這當然毋庸置疑。
對應的模板文件(包括對應的配置文件,布局文件,包含文件)有更新,緩存會自動更新。注意,如果對應的模板文件有更新,緩存介紹那幅圖,就會走中間的那條路,也就是說他會經過模板引擎和PHP模塊。
緩存文件的有效時間過期,會自動更新。默認的時間是3600秒。
<?phpinclude "./libs/Smarty.class.php";$smarty = new Smarty;//開啟緩存,caching是$smarty對象的屬性,等于1表示true,真,表示緩存已開啟//注意,開啟的是頁面緩存$smarty -> caching = 1;//修改緩存文件的有效時間$smarty -> cache_lifetime = 20; //20秒$smarty->assign('animal',array('dog','cat','tiger'));$smarty->display('index.html');上圖我給它設置的是20秒,20秒過后將自動更新。注意,它是重新生成,把原來的給覆蓋掉。
display方法執行時:
4. 判斷緩存是否開啟
5. 判斷模板文件是否有更新(如果有更新,3,4都省略)
6. 判斷緩存文件是否存在(緩存文件時間是否過期)
7. 判斷混編文件是否存在
8. 展示模板內容
9. 緩存開啟,生成緩存文件
單模板多緩存制作
一個模板生成多個緩存文件。
index.php頁面:
index.html頁面:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body><h2>單模板多緩存</h2>顯示商品信息<br/>第{$smarty.get.page}頁數據<br> </body> </html>在地址欄上xxx?page=4,那么結果就是:
當你第二次在地址欄上xxx?page=1,那么結果還是4,page等于2,結果還是4,因為你開啟了緩存,所以在第一次訪問時就已經緩存,第二次,第三次…都是第一次的結果,哪怎么辦?解決辦法如下:
這樣,如果page等于1,哪就是第1頁,page等于2,結果就是第二頁,一個模板生成多個緩存。
局部不緩存
?緩存頁面可以把全部頁面數據都給緩存起來,其中有些數據不適合緩存,例如:天氣信息,用戶信息等等,這樣就需要設置"局部不緩存"。
緩存集合使用
?緩存集合 是單模板多緩存的升級用戶,一個模板可以變著花樣的生成許多緩存文件。
?以上篩選商品的五種條件,做“數學的排列組合”,每種情況都生成一個緩存文件。
index.php:
index.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body><!-- ?brand=apple&price=2002&network=cmcc&big=2 --><h2>緩存集合</h2>商品展示<br/>條件:品牌:{$smarty.get.brand}<br/>價格:{$smarty.get.price}<br/>網絡:{$smarty.get.network}<br/>屏幕大小:{$smarty.get.big}<br/> </body> </html>解決辦法:
<?php include "./libs/Smarty.class.php"; $smarty = new Smarty; $smarty -> caching = 1; $brand = $_GET['brand']; $price = $_GET['price']; $network = $_GET['network']; $big = $_GET['big']; //diaplay(模板,mark1|mark2|mark3|mark4); “/”也可以 //對各種mark做排列組合,每種情況都生成緩存文件 $smarty->display('index1.html',$brand."|".$price."|".$network."|".$big);說白了,就是用戶的每一次篩選都會生成一個緩存文件,但前提是緩存文件已經有了,就是篩選條件跟你的篩選條件一樣,如果沒有一個緩存文件的篩選條件跟你的篩選條件一樣,就生成一個新的緩存文件,不知道你們懂不懂我的意思。
$smarty->force_cache=true;上面的代碼表示強制重新生成緩存文件,也就是說,舊的緩存文件它就不走了。
刪除緩存:clearCache(模板名稱) 刪除改模板生成的所有緩存文件。clerCache(模板,標志) 刪除指定模板,指定標志開始的全部緩存文件。clearAllCache() 刪除全部緩存文件。clearCache(null,標志),我不管哪個模板,只有是以這個標志開始的緩存文件,我都刪除。
?比如一個緩存文件apple^2002^cmcc^2^13260ad4c0d4fc592b81d3a3acaac4c453655788.index1.html.php我想刪除這個緩存文件,這么刪:
總結
以上是生活随笔為你收集整理的Smarty自学笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JdbcTemplate查询数据 三种c
- 下一篇: cad2017插入电气符号_电气电气CA