一,PHP指令碼與動態網頁面。
PHP指令碼是一種伺服器端指令碼程式,可通過嵌入等方法與HTML檔案混合,也可以類,函數封裝等形式,以模板的方式對使用者請求進行處理。無論以何種方式,它的基本原理是這樣的。由用戶端提出請求,請求某一頁面 -----> WEB伺服器引入指定相應指令碼進行處理 -----> 指令碼被載入伺服器 -----> 由伺服器指定的PHP解析器對指令碼進行解析形成HTML語言形式 ----> 將解析後的HTML語句以包的方式傳回給瀏覽器。由此不難看出,在頁面發送到瀏覽器後,PHP就不存在了,已被轉化解析為HTML語句。客戶請求為一動態檔案,事實上並沒有真正的檔案存在在那裡,是PHP解析而成相對應的頁面,然後發送回瀏覽器。這種頁面處理方式被稱為“動態網頁面”。
二,靜態頁面。
靜態頁面是指在伺服器端確實存在的僅含HTML以及JS,CSS等用戶端運行指令碼的頁面。它的處理方式是。由用戶端提出請求,請求某一頁面 ----> WEB伺服器確認並載入某一頁面 ----> WEB伺服器將該頁面以包的形式傳遞迴瀏覽器。由這一過程,我們對比一下動態網頁面,即可方現。動態網頁面需由WEB伺服器的PHP解析器進行解析,而且通常還需串連資料庫,進行資料庫存取操作,然後才能形成HTML語言資訊包;而靜態頁面,無須解析,無須串連資料庫,直接發送,可大大減輕伺服器壓力,提高伺服器負載能力,大幅提供頁面開啟速度和網站整體開啟速度。但其缺點是,不能動態地對請求進行處理,伺服器上必須確實存在該檔案。
三,模板及模板解析。
模板即尚未填充內容html檔案。例如:
temp.html
Code:
複製代碼 代碼如下:<HTML>
<TITLE>{ title }</TITLE>
<BODY>
this is a { file } file's templets
</BODY>
</HTML>
PHP處理:
templetest.php
Code:
$title = "拓邁國際測試模板";
$file = "TwoMax Inter test templet,
author:Matrix@Two_Max";
$fp = fopen ("temp.html","r");
$content = fread ($fp,filesize ("temp.html"));
$content .= str_replace ("{ file }",$file,$content);
$content .= str_replace ("{ title }",$title,$content);
echo $content;
?>
模板解析處理,即將經PHP指令碼解析處理後得出的結果填充(content)進模板的處理過程。通常藉助於模板類。目前較流行的模板解析類有phplib,smarty,fastsmarty等等。模板解析處理的原理通常為替換。也有些程式員習慣將判斷,迴圈等處理放進模板檔案中,用解析類處理,典型應用為block概念,簡單來說即為一個迴圈處理。由PHP指令碼指定迴圈次數,如何迴圈代入等,再由模板解析類具體實施這些操作。
好了,對比過靜態頁面與動態網頁面各自的優劣,現在我們就來說說,如何用PHP產生靜態檔案。
PHP產生靜態頁面並不是指PHP的動態解析,輸出HTML頁面,而是指用PHP建立HTML頁面。同時因為HTML的不可寫性,我們建立的HTML若有修改,則需刪掉重建即可。(當然你也可以選擇用正則進行修改,但個人認為那樣做倒不如刪掉重建來得快捷,有些得不償失。)
言歸正傳。用過PHP檔案操作函數的PHP FANS知道,PHP中有一個檔案操作函數fopen,即開啟檔案。若檔案不存在,則嘗試建立。這即是PHP可以用來建立HTML檔案的理論基礎。只要用來存放HTML檔案的檔案夾有寫入權限(即許可權定義0777),即可建立檔案。(針對UNIX系統而言,Win系統無須考慮。)仍以上例為例,若我們修改最後一句,並指定在test目錄下產生一個名為test.html的靜態檔案:
Code: 複製代碼 代碼如下:<?php
$title = "拓邁國際測試模板";
$file = "TwoMax Inter test templet,
author:Matrix@Two_Max";
$fp = fopen ("temp.html","r");
$content = fread ($fp,filesize ("temp.html"));
$content .= str_replace ("{ file }",$file,$content);
$content .= str_replace ("{ title }",$title,$content);
// echo $content;
$filename = "test/test.html";
$handle = fopen ($filename,"w"); //開啟檔案指標,建立檔案
/*
檢查檔案是否被建立且可寫
*/
if (!is_writable ($filename)){
die ("檔案:".$filename."不可寫,請檢查其屬性後重試!");
}
if (!fwrite ($handle,$content)){ //將資訊寫入檔案
die ("組建檔案".$filename."失敗!");
}
fclose ($handle); //關閉指標
die ("建立檔案".$filename."成功!");
?>
實際應用中常見問題解決方案參考:
一,文章列表問題:
在資料庫中建立欄位,記錄檔案名稱,每產生一個檔案,將自動產生的檔案名稱存入資料庫,對於推薦文章,只需指向存放靜態檔案的指定檔案夾中的該頁面即可。利用PHP操作處理文章列表,存為字串,產生頁面時替換此字串即可。如,在頁面中放置文章列表的表格加入標記{ articletable },而在PHP處理檔案中:
Code: 複製代碼 代碼如下:<?php
$title = "拓邁國際測試模板";
$file = "TwoMax Inter test templet,
author:Matrix@Two_Max";
$fp = fopen ("temp.html","r");
$content = fread ($fp,filesize ("temp.html"));
$content .= str_replace ("{ file }",$file,$content);
$content .= str_replace ("{ title }",$title,$content);
// 產生列表開始
$list = '';
$sql = "select id,title,filename from article";
$query = mysql_query ($sql);
while ($result = mysql_fetch_array ($query)){
$list .= ''.$result['title'].'';
}
$content .= str_replace ("{ articletable }",$list,$content);
//產生列表結束
// echo $content;
$filename = "test/test.html";
$handle = fopen ($filename,"w"); //開啟檔案指標,建立檔案
/*
檢查檔案是否被建立且可寫
*/
if (!is_writable ($filename)){
die ("檔案:".$filename."不可寫,請檢查其屬性後重試!");
}
if (!fwrite ($handle,$content)){ //將資訊寫入檔案
die ("組建檔案".$filename."失敗!");
}
fclose ($handle); //關閉指標
die ("建立檔案".$filename."成功!");
?>
二,分頁問題。
如我們指定分頁時,每頁20篇。某子頻道列表內文章經資料庫查詢為45條,則,首先我們通過查詢得到如下參數:1,總頁數;2,每頁篇數。第二步,for ($i = 0; $i < allpages; $i++),頁面元素擷取,分析,文章產生,都在此迴圈中執行。不同的是,die ("建立檔案".$filename."成功!";這句去掉,放到迴圈後的顯示,因為該語句將中止程式執行。例:
Code: 複製代碼 代碼如下:$fp = fopen ("temp.html","r");
$content = fread ($fp,filesize ("temp.html"));
$onepage = '20';
$sql = "select id from article where channel='$channelid'";
$query = mysql_query ($sql);
$num = mysql_num_rows ($query);
$allpages = ceil ($num / $onepage);
for ($i = 0;$i<$allpages; $i++){
if ($i == 0){
$indexpath = "index.html";
} else {
$indexpath = "index_".$i."html";
}
$start = $i * $onepage;
$list = '';
$sql_for_page = "select name,filename,title from article where channel='$channelid' limit $start,$onepage";
$query_for_page = mysql_query ($sql_for_page);
while ($result = $query_for_page){
$list .= ''.$title.'';
}
$content = str_replace ("{ articletable }",$list,$content);
if (is_file ($indexpath)){
@unlink ($indexpath); //若檔案已存在,則刪除
}
$handle = fopen ($indexpath,"w"); //開啟檔案指標,建立檔案
/*
檢查檔案是否被建立且可寫
*/
if (!is_writable ($indexpath)){
echo "檔案:".$indexpath."不可寫,請檢查其屬性後重試!"; //修改為echo
}
if (!fwrite ($handle,$content)){ //將資訊寫入檔案
echo "組建檔案".$indexpath."失敗!"; //修改為echo
}
fclose ($handle); //關閉指標
}
fclose ($fp);
die ("產生分頁檔案完成,如產生不完全,請檢查檔案許可權系統後重建!");
?>
大致思路如此,其中如其它資料產生,資料輸入輸出檢查,分頁內容指向等可酌情在頁面中加入。
在實際文章系統處理過程當中,還有許多問題有待考慮,與動態網頁面不同之處,需注意的地方還有很多。但大致思路即是如此,其它方面可舉一反三而得。
用PHP製作靜態網站的模板架構
模板能夠改善網站的結構。本文闡述如何通過PHP 4的一個新功能和模板類,在由大量靜態HTML頁面構成的網站中巧妙地運用模板控制頁面配置。
提綱:
===================================
分離功能和布局
避免頁面元素重複
靜態網站的模板架構
===================================
分離功能和布局
首先我們來看看應用模板的兩個主要目的:
分離功能(PHP)和布局(HTML)
避免頁面元素重複
第一個目的是談論得最多的目的,它設想的情形是:一組程式員編寫用於產生頁面內容的PHP指令碼,同時另一組設計人員設計HTML和圖形以控制頁面的最終外觀。分離功能和布局的基本思想就是使得這兩組人能夠各自編寫和使用獨立的一組檔案:程式員只需關心那些只包含PHP代碼的檔案,無需關心頁面的外觀
;而頁面設計人員可以用自己最熟悉的可視化編輯器設計頁面配置,無需擔心破壞任何嵌入到頁面的PHP代碼。
如果你曾經看過幾個關於PHP模板的教程,那麼你應該已經明白模板的工作機制。考慮一個簡單的頁面局部:頁面的上方是頁頭,左邊是導航條,其餘部分是內容地區。這種網站可以擁有如下模板檔案: 複製代碼 代碼如下:<!-- main.htm -->
<html>
<head><title>模板樣本</title></head>
<body>
<table><tr><td>{HEADER}</td></tr>
<tr><td>{LEFTNAV}</td><td>{CONTENT}</td></tr>
</table>
</body></html>
<!-- header.htm -->
<img src="sitelogo.jpg">
<!-- leftnav.htm -->
<br><a href="foo">Foo</a>
<br><a href="bar">Bar</a>
可以看出頁面如何由這些模板構造而成:main模板控制著整個頁面的布局;header模板和leftnav模板控制著頁面的公用元素。花括弧“{}”裡面的標識符是內容預留位置。使用模板最主要的好處在於介面設計者能夠按照自己的意願編輯這些檔案,比如設定字型、修改顏色和圖形,或者完全地改變頁面的布局。介面設計者可以用任何普通HTML編輯器或者視覺化檢視編輯這些頁面,因為這些檔案都只包含HTML代碼,沒有任何PHP代碼。
PHP代碼全部儲存到單獨的檔案中,這個檔案也就是由頁面URL實際調用的檔案。Web伺服器通過PHP引擎解析該檔案,然後把結果返回給瀏覽器。一般地,PHP代碼總是動態地產生頁面內容,比如查詢資料庫或者執行某種計算等。下面是一個例子: 複製代碼 代碼如下:<?php
// example.php
require('class.FastTemplate.php');
$tpl = new FastTemplate('.');
$tpl->define( array( 'main' => 'main.htm',
'header' => 'header.htm',
'leftnav' => 'leftnav.htm' ) );
// 此處的PHP代碼設定$content使其包含合適的頁面內容
$tpl->assign('CONTENT', $content);
$tpl->parse('HEADER', 'header');
$tpl->parse('LEFTNAV', 'leftnav');
$tpl->parse('MAIN', 'main');
$tpl->FastPrint('MAIN');
?>
這裡我們使用的是流行的FastTemplate模板類,但其基本思路對於其他許多模板類來說都一樣。首先你執行個體化一個類,告訴它到哪裡去尋找模板檔案以及哪一個模板檔案與頁面的哪部分對應;接下來是產生頁面內容,把結果賦予內容的標識符;然後,依次解析各個模板檔案,模板類將執行必要的替換操作;最後把解析結果輸出到瀏覽器。
這個檔案完全由PHP代碼構成,不包含任何HTML代碼,這是它最大的優點。現在,PHP程式員可以集中精力編寫產生頁面內容的代碼,而不必為了如何產生HTML去正確地格式化最終頁面而擔心。
你可以使用這種方法和上面的檔案構造出一個完整的網站。如果PHP代碼是以URL中的查詢字串為基礎產生頁面內容,例如http://www.foo.com/example.php?article=099,你可以據此構造出一個完整的雜誌網站。
很容易看出採用模板還有第二個好處。如上例所示,頁面左邊的導航條單獨儲存為一個檔案,我們只需編輯這一個模板檔案就可以改變網站所有頁面左邊的導航條。
避免頁面元素重複
“這確實不錯”,你也許會想,“我的網站主要就是由大量的靜態頁面構成。現在我可以從所有頁面中刪除它們的公用部分,要更新這些公用部分實在太麻煩了。以後我就可以用模板製作出很容易維護的統一頁面配置。”但事情並非這麼簡單,“大量的靜態頁面”道出了問題的所在。
請考慮上面的例子。這個例子實際上只有一個example.php頁面,它之所以能夠產生整個網站的所有頁面,是因為它利用了URL中的查詢字串從資料庫之類的資訊源動態地構造出頁面。
我們之中的大多數人所啟動並執行網站並不一定都有資料庫支援。我們的網站大多數由靜態頁面構成,然後用PHP在這裡、那裡加上一些動態功能,比如搜尋引擎、反饋表單等。那麼,如何在這種網站上應用模板呢?
最簡單的方法是為每一個頁面複製一份PHP檔案,
然後在每一個頁面中把PHP代碼裡代表內容的變數設定成合適的頁面內容。例如,假設有三個頁面,它們分別是首頁(home)、關於(about)和產品(product),我們可以用三個檔案分別產生它們。這三個檔案的內容都類如: 複製代碼 代碼如下:<?php
// home.php
require('class.FastTemplate.php');
$tpl = new FastTemplate('.');
$tpl->define( array( 'main' => 'main.htm',
'header' => 'header.htm',
'leftnav' => 'leftnav.htm' ) );
$content = "<p>歡迎訪問</p>
<img src=\"demo.jpg\">
<p>希望你能夠喜歡本網站</p>";
$tpl->assign('CONTENT', $content);
$tpl->parse('HEADER', 'header');
$tpl->parse('LEFTNAV', 'leftnav');
$tpl->parse('MAIN', 'main');
$tpl->FastPrint('MAIN');
?>
顯然,這種方法有三個問題:我們必須為每一個頁面複製這些複雜的、牽涉到模板的PHP代碼,這與重複公用頁面元素一樣使得頁面難以維護;現在檔案又混合了HTML和PHP代碼;為內容變數賦值將變得非常困難,因為我們必須處理好大量的特殊字元。
解決這個問題的關鍵就在於分離PHP代碼和HTML內容,雖然我們不能從檔案中刪除所有的HTML內容,但可以移出絕大多數PHP代碼。
靜態網站的模板架構
首先,我們象前面一樣為所有的頁面公用元素以及頁面整體布局編寫模板檔案;然後從所有的頁面刪除公用部分,只留下頁面內容;接下來再在每個頁面中加上三行PHP代碼,如下所示: 複製代碼 代碼如下:<?php
<!-- home.php -->
<?php require('prepend.php'); ?>
<?php pageStart('Home'); ?>
<h1>你好</h1>
<p>歡迎訪問</p>
<img src="demo.jpg">
<p>希望你能夠喜歡本網站</p>
<?php pageFinish(); ?>
?>
這種方法基本上解決了前面提到的各種問題。現在檔案裡只有三行PHP代碼,而且沒有任何一行代碼直接涉及到模板,因此要改動這些代碼的可能性極小。此外,由於HTML內容位於PHP標記之外,所以也不存在特殊字元的處理問題。我們可以很容易地將這三行PHP代碼加入到所有靜態HTML頁面中。
require函數引入了一個PHP檔案,這個檔案包含了所有必需的與模板相關的PHP代碼。其中pageStart函數設定模板對象以及頁面標題,pageFinish函數解析模板然後產生結果發送給瀏覽器。
這是如何?的呢?為什麼在調用pageFinish函數之前檔案中的HTML不會發送給瀏覽器?答案就在於PHP 4的一個新功能,這個功能允許把輸出到瀏覽器的內容截獲到緩衝區之中。讓我們來看看prepend.php的具體代碼: 複製代碼 代碼如下:<?php
require('class.FastTemplate.php');
function pageStart($title = '') {
GLOBAL $tpl;
$tpl = new FastTemplate('.');
$tpl->define( array( 'main' => 'main.htm',
'header' => 'header.htm',
'leftnav'=> 'leftnav.htm' ) );
$tpl->assign('TITLE', $title);
ob_start();
}
function pageFinish() {
GLOBAL $tpl;
$content = ob_get_contents();
ob_end_clean();
$tpl->assign('CONTENT', $content);
$tpl->parse('HEADER', 'header');
$tpl->parse('LEFTNAV', 'leftnav');
$tpl->parse('MAIN', 'main');
$tpl->FastPrint('MAIN');
}
?>
pageStart函數首先建立並設定了一個模板執行個體,然後啟用輸出緩衝。此後,所有來自頁面本身的HTML內容都將進入緩衝。pageFinish函數取出緩衝中的內容,然後在模板對象中指定這些內容,最後解析模板並輸出完成後的頁面。
這就是整個模板架構全部的工作過程了。首先編寫包含了網站各個頁面公用元素的模板,然後從所有頁面中刪除全部公用的頁面配置代碼,代之以三行永遠無需改動的PHP代碼;再把FastTemplate類檔案和prepend.php加入到包含路徑,這樣你就得到了一個頁面配置可以集中控制的網站,它有著更好的可靠性和可維護性,而且網站級的大範圍修改也變得相當容易。
本文下載包包含
了一個可啟動並執行樣本網站,它的代碼注釋要比前面的代碼注釋更詳細一些。FastTemplate類可以在http://www.thewebmasters.net/找到,最新的版本號碼是1.1.0,那裡還有一個用於保證該類在PHP 4中正確啟動並執行小補丁。本文下載代碼中的類已經經過該補丁的修正。
PHP簡易產生靜態頁面 複製代碼 代碼如下:<?php
/*
* 檔案名稱:index.php
*/
require "conn.php";
$query = "select * from news order by datetime desc";
$result = mysql_query($query);
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=??????">
<title>NEWS</title>
</head>
<body>
<table width="500" border="1" align="center">
<tr>
<td>標題</td>
<td width="200">發布時間</td>
</tr>
<?
while($re = mysql_fetch_array($result)){
?>
<tr>
<td><a href="<?= $re["newsid"].".html"?>"><?= $re["title"]?></a></td>
<td><?= $re["datetime"]?></td>
</tr>
<?
}
?>
<tr>
<td> </td>
<td><a href="addnews.php">添加新聞</a></td>
</tr>
</table>
</body>
</html>
複製代碼 代碼如下:<?php
/*
檔案名稱:AddNews.php
簡易動態添加產生靜態新聞頁面
#
# 表的結構 `news`
#
CREATE TABLE `news` (
`newsid` int(11) NOT NULL auto_increment,
`title` varchar(100) NOT NULL default '',
`content` text NOT NULL,
`datetime` datetime NOT NULL default '0000-00-00 00:00:00',
KEY `newsid` (`newsid`)
) TYPE=MyISAM AUTO_INCREMENT=11 ;
*/
?>
用PHP產生靜態網頁的兩個函數
在最近幾年,全球資訊網(也稱環球資訊網,即WWW)不斷改變資訊處理技術的面貌。WEB已經快速地成為一種有效媒介,並適合人們和商業溝通和協作。幾乎所有的資訊技術領域都普遍受到WEB的影響。Web訪問帶來更多使用者和更多資料,這意味著給伺服器和資料庫更多壓力和終端使用者得到越來越慢的響應速度。與不斷靠增加CPU,磁碟機及記憶體來跟上這種增長的需求相比, WEB動態網頁面靜態化應該是一個更實用,更經濟的選擇。
用PHP實現WEB動態網頁靜態化的具體實現函數如function gen_static_file()所示
複製代碼 代碼如下:function gen_static_file($program, $filename)
{
$program 1= "/usr/local/apache/htdocs/php/" . $program;
$filename1 = "/usr/local/apache/htdocs/ static_html/" . $filename;
$cmd_str = "/usr/local/php4/bin/php " . $program1 . " } " . $filename1 . " ";
system($cmd_str);
echo $filename . " generated.〈br〉";
}
這個函數是實現靜態化的關鍵,即PHP動態網頁面程式不是被送到瀏覽器中,而是輸入到名為$filename的檔案中去(2)。兩個參數中$program是PHP動態網頁面程式,$filename是產生的靜態頁面的名字(可根據需要自己制定命名規則,這一點很重要,見下文),/usr/local/php4/bin/php是PHP中具有把程式輸入檔案功能的部分,System是PHP中執行外部命令的函數。我們還可以看出所有產生動態網頁面的php程式需放在/php/目錄下,所有新產生的靜態頁面則會出現在/static_html/目錄下(這些路徑可以根據具體需要設定)。
下面讓我們舉個具體例子,看一下college_static.php的靜態頁面是怎樣產生的。
複製代碼 代碼如下:function gen_college_static ()
{
for ($i = 0; $i 〈= 32; $i++〉
{
putenv("province_id=" . $i); //*.php檔案從資料庫取資料時要用到。
$filename = " college_static". $i . ".html";
gen_static_file("college_static.php", $filename);
}
從這個函數我們可以看到通過調用函數gen_static_file(), college_static.php經過靜態化,變成了33個靜態頁面college.static0.html~college.static33.html,其中$filename會隨著$I的變化而變化。當然也可以從資料庫中直接取值,來控制產生的靜態頁面的個數和名字,其他程式對產生的靜態頁面的調用應和靜態頁面的命名規則一致。