Smarty執行個體教程執行個體篇( 使用PHP內建MYSQL函數)

來源:互聯網
上載者:User

從本節開始我們來學習一下如果把Smarty應用到實際的例子中. 為了示範說明,我將以前寫的一個網站作為執行個體來講來下.先說明一下, 我本人的美術功底不是很強,所以設計出來的頁面不太好看,大家就對付著看吧
在看本文之前,可以先看看indexbak.htm與newsbak.htm,它們是我們產生後的例圖。

一、 首先來說明一下我們將要使用到的資料庫,下面我先將資料庫源檔案給大家例出來:


CREATE DATABASE News;

USE News;

/****************************
*
* 表 名: tb_news_ch
* 用 途: 國內新聞表
*
****************************/
CREATE TABLE tb_news_ch
(
iNewsID interger(11) primary key auto_increment,
vcNewsTitle varchar(50) not null,
ltNewsContent longtext not null
);


/****************************
*
* 表 名: tb_news_in
* 用 途: 國際新聞表
*
****************************/
CREATE TABLE tb_news_in
(
iNewsID interger(11) primary key auto_increment,
vcNewsTitle varchar(50) not null,
ltNewsContent longtext not null
);


/****************************
*
* 表 名: tb_news_mu
* 用 途: 娛樂新聞表
*
****************************/

CREATE TABLE tb_news_mu
(
iNewsID interger(11) primary key auto_increment,
vcNewsTitle varchar(50) not null,
ltNewsContent longtext not null
);
我這裡簡單的將資料庫說明一下.

第一個問題:
大家可以看到,其實3個資料表的欄位名都一樣,那麼為什麼不把它們合并成一個資料表呢,答案很簡單:效率,在開發的時候我們可能感覺不出有什麼可提高效率的地方,不過大家想想,當這個網站運行一段時間後,它的新聞資料量就會變的很大,而且考慮到如果將來網站做大後可能將各個類型分離出來形成類似china.xxx.com, international.xxx.com, music.xxx.com,將每一欄目獨立分出去物理上做成一個單獨的網站,到那時如果新聞還是合起來放置的話就會造成資料庫瓶頸,所以針對當前的網站,我認為還是分開的比較合理.

第二個問題:
有人可能問了,你在欄位前加的i, vc,lt幹什麼用?這裡是按照欄位類型來命名的, 這也是一種良好風格的體現,將類型首碼放在變數前,使用使用者不用看欄位定義就可以知道欄位是什麼類型,這是從微軟的匈牙利命名法中參考過來的,在資料庫設計時,我先將每種類型定義成1--3個字母,然後在每個欄位前加相應的代碼來代表它的類型.像上邊,我將各個資料庫欄位類型定義為:

integer i
varchar vc
longtext lt
char c
....

在使用的時候,你可以往每個資料表中輸入5條資料記錄以備我們在調試執行個體時使用.

二、樣本網站目錄結構:

PHP代碼:--------------------------------------------------------------------------------
+Web (網站根目錄)
|
|----+comm (Smarty相關文檔目錄)
| |
| |----+plugins (Smarty外掛程式目錄)
| |-----Config_File.class.php (Smarty設定檔)
| |-----Smarty.class.php (Smarty類主檔案)
| |-----Smarty_Compiler.class.php (Smarty編譯類檔案)
|
|----+cache (Smarty緩衝目錄,*nix下保證讀寫權限)
|
|----+templates (網站模板檔案存放目錄)
| |
| |----header.tpl(頁面頁頭模板檔案)
| |----index.tpl(網站首頁模板檔案)
| |----foot.tpl(頁面頁尾模板檔案)
| |----news.tpl (新聞頁模板檔案)
|
|
|----+templates_c (模板檔案編譯後存放目錄,*nix下保證讀寫權限)
|
|----+css (網站CSS檔案目錄)
|
|----+image (網站圖片目錄)
|
|----+media (網站Flash動畫存放目錄)
|
|----indexbak.htm (首頁原始效果圖)
|
|----newsbak,htm (新聞頁原始效果圖)
|
|----index.php (Smarty首頁程式檔案)
|
|----news.php (Smarty新聞顯示檔案)
|
|----常式說明.txt (目錄說明)
|
|----資料庫建立檔案.txt (資料庫的建立文檔)

詳細情況請大家下載執行個體後對照結構圖。

--------------------------------------------------------------------------------

三、模板中的執行個體片段:

1. index.tpl:

index.tpl是網站首頁的模板類,開啟它的源檔案後我們可以首先看到這麼二句:
==================================================
1. <{*下面這一句為本頁面的頁面頭*}>
2. <{include file="header.tpl"}>
==================================================
第 1 句大家都知道了,是模板注釋
第 2 句表示在當前位置要包含另一個檔案,什麼檔案呢,header.tpl,這裡的這個header.tpl是頁面的標準頁標頭檔,把它單獨拿出來是為將這一部分獨立出來,以便在在其它頁面進行重用,習慣上要把頁標頭檔寫在一個table中,但因為我的執行個體是早已做好的,所以有些不符合規範。

再來看最後一句:
=================================================
3. <{include file="foot.tpl"}>
=================================================
不用說大家都明白了,就是包含一個頁尾檔案。

再看看國內新聞部分的模板代碼:


CODE:[Copy to clipboard]<table width="100%" border="0" cellpadding="0" cellspacing="0" bgcolor="#B9E9FF">
<tr>
<td height="115" width="10"></td>
<td valign="top" width="295" bgcolor="#B9E9FF">
<{section name=loop loop=$News_CH}>
<li class="newsfont"><a href="news.php?type=1&id=<{$News_CH[loop].NewsID}>" class="newsfont"><{$News_CH[loop].NewsTitle}></a>
<{/section}>
</td>
</tr>
</table>
大家關鍵看<{section}>與<{/section}>,它們之外的那一部分是為了更好的理解代碼的意思而列出來的。能看明白嗎?這裡將以前講過的內容複習一遍:定義了一個section迴圈模板塊,名字叫loop, 要迴圈的是$News_CH這個數組,以<a href="xxxx">處將為當前的新聞產生一個連結,地址為news.php?type=1&id=xxx,這裡的xxx是從資料庫裡提取的iNewsID,指的是要在新聞顯示頁裡顯示編號為id的新聞。$News_CH[loop].NewsTitle這種表示形式來看的懂吧?看不懂的話看看上一節講過的《Smarty執行個體教學 ---程式設計》部分中的<{section}>文法。
也許大家對<{}>感覺有點陌生,這裡的<{}>為模板語句定義塊,在前2節我們都使用{},但因為這裡是具體的應用,所以就不取{}了,使用大家習慣的<{}>來表示,當然這在.php檔案中要設定的。

再看國際新聞與娛樂新聞的代碼:


國際新聞:


CODE:[Copy to clipboard]<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="295" height="115" valign="top">
<{section name=loop loop=$News_IN}>
<li class="newsfont"><a href="news.php?type=2&id=<{$News_IN[loop].NewsID}>" class="newsfont"><{$News_IN[loop].NewsTitle}></a>
<{/section}>
</td>
</tr>
</table>
娛樂新聞:


CODE:[Copy to clipboard]<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="296" height="115" valign="top">
<{section name=loop loop=$News_MU}>
<li class="newsfont"><a href="news.php?type=3&id=<{$News_MU[loop].NewsID}>" class="newsfont"><{$News_MU[loop].NewsTitle}></a>
<{/section}>
</td>
</tr>
</table>
有沒有看出有什麼不同? loop部分不同,loop指的是要迴圈的數組,這裡要注意的,不可將多個section的loop指定為同一個值,那樣的話Smarty進行分析模板的時候就會將兩個具有相同名字的section同時分析,產生兩個一樣的記錄。

看到這裡,有人就會產生疑問:迴圈塊我已經有了,我怎麼才能就它在當前位置只顯示我們想要的記錄數呢?這個問題簡單,我們對Smarty的section迴圈塊的迴圈次數控制是在.php檔案中控制要替換這個迴圈塊的數組來決定的,在設計範本時我們不用考慮。


其次,我們再來看看news.tpl:

1. 看這一句:
<title><{$NewsTitle}> ----天驕資訊網</title>
將要顯示的新聞頁的標題顯示為新聞標題 + "----天驕資訊網"
2. 新聞標題:
<div align="center" class="NewsTitle"><{$NewsTitle}></div>
這裡又設定了一個模板變數$NewsTitle,意思說要.php將$NewsTitle(包括標題列)替換為資料庫中當前新聞的標題。
3. 新聞內容:
<p><{$NewsContext}></p>
這一句也容易,在當前位置顯示新聞內容。

當然,這裡只是簡單的將新聞列出來了,在實際應用時你還可以把文章出處,發表時間,作者,相關新聞一起列出來,這裡就不作多的討論了.


三、程式部分:

1. 大家先來看看index.php的源檔案,然後我們再來慢慢分析它的作用:

index.php


<?php

2. include_once("./comm/Smarty.class.php"); //包含smarty類檔案
3. define("NUM", 5); //定義每次顯示的新聞條數

4. $smarty = new Smarty(); //建立smarty執行個體對象$smarty
$smarty->templates_dir = "./templates"; //設定模板目錄
$smarty->compile_dir = "./templates_c"; //設定編譯目錄
$smarty->cache_dir = "./cache"; //設定緩衝目錄
$smarty->cache_lifetime = 60 * 60 * 24; //設定緩衝時間
$smarty->caching = false; //這裡是調試時設為false,發布時請使用true
$smarty->left_delimiter = "<{"; //設定左邊界符
$smarty->right_delimiter = "}>"; //設定右邊界符


5. $db = mysql_connect("localhost", "root", "");
mysql_select_db("News", $db);


//這裡將處理國內新聞部分
6. $strQuery = "SELECT iNewsID, vcNewsTitle FROM tb_news_ch ORDER BY iNewsID DESC";
$result = mysql_query($strQuery);
$i = NUM;
7. while(($row = mysql_fetch_array($result)) && $i > 0)
{
$array[] = array("NewsID"=>substr($row["iNewsID"], 0, 40),
"NewsTitle"=>substr($row["vcNewsTitle"], 0, 40));

$i--;
}
8. $smarty->assign("News_CH", $array);
9. unset($array);
mysql_free_result();


10. //這裡處理國際新聞部分
$strQuery = "SELECT iNewsID, vcNewsTitle FROM tb_news_in ORDER BY iNewsID DESC";
$result = mysql_query($strQuery);
$i = NUM;
while(($row = mysql_fetch_array($result)) && $i > 0)
{
$array[] = array("NewsID"=>substr($row["iNewsID"], 0, 40),
"NewsTitle"=>substr($row["vcNewsTitle"], 0, 40));

$i--;
}
$smarty->assign("News_IN", $array);
unset($array);
mysql_free_result();


11. //這裡將處理娛樂新聞部分
$strQuery = "SELECT iNewsID, vcNewsTitle FROM tb_news_mu ORDER BY iNewsID DESC";
$result = mysql_query($strQuery);
$i = NUM;
while(($row = mysql_fetch_array($result)) && $i > 0)
{
$array[] = array("NewsID"=>substr($row["iNewsID"], 0, 40),
"NewsTitle"=>substr($row["vcNewsTitle"], 0, 40));

$i--;
}
$smarty->assign("News_MU", $array);
unset($array);
mysql_free_result();


mysql_close($db);

//編譯並顯示位於./templates下的index.tpl模板
12. $smarty->display("index.tpl");
?>


為了方便說明,我把每一個要說明的地方都標了號,下面就來說說每一個部分的作用:

1. 程式注釋, 風格問題,我多次在程式中加這個就是為了讓讀者也養成這種習慣.
2. 檔案包含. 這一句意思是把Smarty的類檔案包含到當前程式檔案中.
3. 常數定義: 定義NUM為5,為新聞顯示條數
4. 設定Smarty參數: 關於裡邊的參數大家可以參考上一節講過的,這裡只想特別說明一下$smarty->cache屬性,在我們的程式調試過程中,要把它設定為false,正式發布的時候將它設計為true就可以實現我們的程式緩衝效果.
5. 資料庫連接: 這一部分我不用說吧?標準的PHP語句.
6. 進行國內新聞尋找SQL語句: 標準的SQL語句,按新題編號降序排序.
7. while():
這一句控制將要顯示的新聞行數.首先給$i賦值為NUM,NUM為我們在開始外定義的一個常量, 在while()的開始判斷處使用$i>0 這個條件,while()每次迴圈時要將$i的值減1,這樣,當它完成5次迴圈時while就會結束.
這裡我們主要來看看$array[]這個數組:
$array[]在理論上為一個二維數組,也就是一個數組中的元素為另一個數組,像上例中,當while()語句結束時,$array就是一個包含5個數組元素的數組,而每一元素又是一個字元索引的數組.而這些字元索引正是在模板中定義section迴圈塊的$news[loop]的屬性值,大家一定要注意這裡要與模板迴圈塊的屬性值相對應,否則將不能顯示出來!
在構建這個二維數組時我們使用了一個substr()方法進行字元截取,這個方法在這裡僅供參考,實際使用當中因為中文為全形字元,使用它時可能會造成亂碼,在以後的例子中我們將使用另一個網友與的csubstr()函數來實現字元截取功能.

8. 對模板中的loop = $News_CH的section迴圈塊進行解析.
大家要注意,使用$smarty->assign("News_CH", $array),assign的第一個參數為section中的loop的值, 第二個參數為上面所建立的數組.

9. 登出$array: $array[]在使用完後要登出,因為使用指派陳述式對$array進行賦值時不會將它清空,而是將新數組作為它的一個元素增加,為了不產生副作用,這裡使用unset()是必需的.

10. 國際新聞處理模組:
同國內新聞處理模組一樣,大家可以對比一下模板與這一段,找找其中有什麼關聯之處.

11. 娛樂新聞處理模組:同上,大家找找其中的關係.相信大家看完會有收穫的.

12. 處理並顯示index.tpl.


2. 下面再來看看news.php的源檔案:

news.php


<?php

include_once("./comm/Smarty.class.php"); //包含smarty類檔案
define("NUM", 5); //定義每次顯示的新聞條數

$smarty = new Smarty(); //建立smarty執行個體對象$smarty
$smarty->templates_dir = "./templates"; //設定模板目錄
$smarty->compile_dir = "./templates_c"; //設定編譯目錄
$smarty->cache_dir = "./cache"; //設定緩衝目錄
$smarty->cache_lifetime = 60 * 60 * 24; //設定緩衝時間
$smarty->caching = false; //這裡是調試時設為false,發布時請使用true
$smarty->left_delimiter = "<{"; //設定左邊界符
$smarty->right_delimiter = "}>"; //設定右邊界符


$db = mysql_connect("localhost", "root", "") or die("資料庫連接錯誤!");
mysql_select_db("News", $db);

$NewsID = $_GET["id"]; //擷取新聞編號
$NewsType = $_GET["type"]; //要顯示的新聞類型
switch($NewsType)
{
case 1:
$dbName = "tb_news_ch";
break;
case 2:
$dbName = "tb_news_in";
break;
case 3:
$dbName = "tb_news_mu";
break;
}

$strQuery = "SELECT vcNewsTitle, ltNewsContent FROM $dbName";
$result = mysql_query($strQuery) or die("資料庫查詢錯誤!");
if($row = mysql_fetch_array($result))
{
$smarty->assign("NewsTitle", $row["vcNewsTitle"]);
$smarty->assign("NewsContent", $row["ltNewsContent"]);

mysql_free_result($result);
$smarty->display("news.tpl");
}

mysql_close($db);

?>


這上面關於Smarty的程式語句主要只有3行:


PHP:[Copy to clipboard]
$smarty->assign("NewsTitle", $row["vcNewsTitle"]);
$smarty->assign("NewsContent", $row["ltNewsContent"]);

mysql_free_result($result);

 

很簡單的將新聞頁中的NewsTitle, NewsContent替換成從資料庫中尋找出來的內容.

好了,關於這一講的Smarty常式學習的初級部分就講到這裡,相信大家學完後會對Smarty的用法有個基本的瞭解,下一節還使用個這個例子來講講如何使用phplib中的DB類來實現對模板的控制.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.