比較詳細PHP生成靜態(tài)頁面教程
當前位置:點晴教程→知識管理交流
→『 技術文檔交流 』
一,PHP腳本與動態(tài)頁面。
PHP腳本是一種服務器端腳本程序,可通過嵌入等方法與HTML文件混合,也可以類,函數封裝等形式,以模板的方式對用戶請求進行處理。無論以何種方式,它的基本原理是這樣的。由客戶端提出請求,請求某一頁面 -----> WEB服務器引入指定相應腳本進行處理 -----> 腳本被載入服務器 -----> 由服務器指定的PHP解析器對腳本進行解析形成HTML語言形式 ----> 將解析后的HTML語句以包的方式傳回給瀏覽器。由此不難看出,在頁面發(fā)送到瀏覽器后,PHP就不存在了,已被轉化解析為HTML語句??蛻粽埱鬄橐粍討B(tài)文件,事實上并沒有真正的文件存在在那里,是PHP解析而成相對應的頁面,然后發(fā)送回瀏覽器。這種頁面處理方式被稱為“動態(tài)頁面”。 二,靜態(tài)頁面。 靜態(tài)頁面是指在服務器端確實存在的僅含HTML以及JS,CSS等客戶端運行腳本的頁面。它的處理方式是。由客戶端提出請求,請求某一頁面 ----> WEB服務器確認并載入某一頁面 ----> WEB服務器將該頁面以包的形式傳遞回瀏覽器。由這一過程,我們對比一下動態(tài)頁面,即可方現。動態(tài)頁面需由WEB服務器的PHP解析器進行解析,而且通常還需連接數據庫,進行數據庫存取操作,然后才能形成HTML語言信息包;而靜態(tài)頁面,無須解析,無須連接數據庫,直接發(fā)送,可大大減輕服務器壓力,提高服務器負載能力,大幅提供頁面打開速度和網站整體打開速度。但其缺點是,不能動態(tài)地對請求進行處理,服務器上必須確實存在該文件。 三,模板及模板解析。 模板即尚未填充內容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等等。模板解析處理的原理通常為替換。也有些程序員習慣將判斷,循環(huán)等處理放進模板文件中,用解析類處理,典型應用為block概念,簡單來說即為一個循環(huán)處理。由PHP腳本指定循環(huán)次數,如何循環(huán)代入等,再由模板解析類具體實施這些操作。 好了,對比過靜態(tài)頁面與動態(tài)頁面各自的優(yōu)劣,現在我們就來說說,如何用PHP生成靜態(tài)文件。 PHP生成靜態(tài)頁面并不是指PHP的動態(tài)解析,輸出HTML頁面,而是指用PHP創(chuàng)建HTML頁面。同時因為HTML的不可寫性,我們創(chuàng)建的HTML若有修改,則需刪掉重新生成即可。(當然你也可以選擇用正則進行修改,但個人認為那樣做倒不如刪掉重新生成來得快捷,有些得不償失。) 言歸正傳。用過PHP文件操作函數的PHP FANS知道,PHP中有一個文件操作函數fopen,即打開文件。若文件不存在,則嘗試創(chuàng)建。這即是PHP可以用來創(chuàng)建HTML文件的理論基礎。只要用來存放HTML文件的文件夾有寫權限(即權限定義0777),即可創(chuàng)建文件。(針對UNIX系統(tǒng)而言,Win系統(tǒng)無須考慮。)仍以上例為例,若我們修改最后一句,并指定在test目錄下生成一個名為test.html的靜態(tài)文件: 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"); //打開文件指針,創(chuàng)建文件 /* 檢查文件是否被創(chuàng)建且可寫 */ if (!is_writable ($filename)){ die ("文件:".$filename."不可寫,請檢查其屬性后重試!"); } if (!fwrite ($handle,$content)){ //將信息寫入文件 die ("生成文件".$filename."失?。?); } fclose ($handle); //關閉指針 die ("創(chuàng)建文件".$filename."成功!"); ?> 實際應用中常見問題解決方案參考: 一,文章列表問題: 在數據庫中創(chuàng)建字段,記錄文件名,每生成一個文件,將自動生成的文件名存入數據庫,對于推薦文章,只需指向存放靜態(tài)文件的指定文件夾中的該頁面即可。利用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"); //打開文件指針,創(chuàng)建文件 /* 檢查文件是否被創(chuàng)建且可寫 */ if (!is_writable ($filename)){ die ("文件:".$filename."不可寫,請檢查其屬性后重試!"); } if (!fwrite ($handle,$content)){ //將信息寫入文件 die ("生成文件".$filename."失敗!"); } fclose ($handle); //關閉指針 die ("創(chuàng)建文件".$filename."成功!"); ?> 二,分頁問題。 如我們指定分頁時,每頁20篇。某子頻道列表內文章經數據庫查詢?yōu)?5條,則,首先我們通過查詢得到如下參數:1,總頁數;2,每頁篇數。第二步,for ($i = 0; $i < allpages; $i++),頁面元素獲取,分析,文章生成,都在此循環(huán)中執(zhí)行。不同的是,die ("創(chuàng)建文件".$filename."成功!";這句去掉,放到循環(huán)后的顯示,因為該語句將中止程序執(zhí)行。例: 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"); //打開文件指針,創(chuàng)建文件 /* 檢查文件是否被創(chuàng)建且可寫 */ if (!is_writable ($indexpath)){ echo "文件:".$indexpath."不可寫,請檢查其屬性后重試!"; //修改為echo } if (!fwrite ($handle,$content)){ //將信息寫入文件 echo "生成文件".$indexpath."失?。?; //修改為echo } fclose ($handle); //關閉指針 } fclose ($fp); die ("生成分頁文件完成,如生成不完全,請檢查文件權限系統(tǒng)后重新生成!"); ?> 大致思路如此,其中如其它數據生成,數據輸入輸出檢查,分頁內容指向等可酌情在頁面中加入。 在實際文章系統(tǒng)處理過程當中,還有許多問題有待考慮,與動態(tài)頁面不同之處,需注意的地方還有很多。但大致思路即是如此,其它方面可舉一反三而得。 用PHP制作靜態(tài)網站的模板框架 模板能夠改善網站的結構。本文闡述如何通過PHP 4的一個新功能和模板類,在由大量靜態(tài)HTML頁面構成的網站中巧妙地運用模板控制頁面布局。 提綱: =================================== 分離功能和布局 避免頁面元素重復 靜態(tài)網站的模板框架 =================================== 分離功能和布局 首先我們來看看應用模板的兩個主要目的: 分離功能(PHP)和布局(HTML) 避免頁面元素重復 第一個目的是談論得最多的目的,它設想的情形是:一組程序員編寫用于生成頁面內容的PHP腳本,同時另一組設計人員設計HTML和圖形以控制頁面的最終外觀。分離功能和布局的基本思想就是使得這兩組人能夠各自編寫和使用獨立的一組文件:程序員只需關心那些只包含PHP代碼的文件,無需關心頁面的外觀 ;而頁面設計人員可以用自己最熟悉的可視化編輯器設計頁面布局,無需擔心破壞任何嵌入到頁面的PHP代碼。 如果你曾經看過幾個關于PHP模板的教程,那么你應該已經明白模板的工作機制??紤]一個簡單的頁面局部:頁面的上方是頁頭,左邊是導航條,其余部分是內容區(qū)域。這種網站可以擁有如下模板文件: . 代碼如下: <!-- 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代碼總是動態(tài)地生成頁面內容,比如查詢數據庫或者執(zhí)行某種計算等。下面是一個例子: . 代碼如下: <?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模板類,但其基本思路對于其他許多模板類來說都一樣。首先你實例化一個類,告訴它到哪里去尋找模板文件以及哪一個模板文件與頁面的哪部分對應;接下來是生成頁面內容,把結果賦予內容的標識符;然后,依次解析各個模板文件,模板類將執(zhí)行必要的替換操作;最后把解析結果輸出到瀏覽器。 這個文件完全由PHP代碼構成,不包含任何HTML代碼,這是它最大的優(yōu)點?,F在,PHP程序員可以集中精力編寫生成頁面內容的代碼,而不必為了如何生成HTML去正確地格式化最終頁面而擔心。 你可以使用這種方法和上面的文件構造出一個完整的網站。如果PHP代碼是以URL中的查詢字符串為基礎生成頁面內容,例如http://www.foo.com/example.php?article=099,你可以據此構造出一個完整的雜志網站。 很容易看出采用模板還有第二個好處。如上例所示,頁面左邊的導航條單獨保存為一個文件,我們只需編輯這一個模板文件就可以改變網站所有頁面左邊的導航條。 避免頁面元素重復 “這確實不錯”,你也許會想,“我的網站主要就是由大量的靜態(tài)頁面構成。現在我可以從所有頁面中刪除它們的公共部分,要更新這些公共部分實在太麻煩了。以后我就可以用模板制作出很容易維護的統(tǒng)一頁面布局。”但事情并非這么簡單,“大量的靜態(tài)頁面”道出了問題的所在。 請考慮上面的例子。這個例子實際上只有一個example.php頁面,它之所以能夠生成整個網站的所有頁面,是因為它利用了URL中的查詢字符串從數據庫之類的信息源動態(tài)地構造出頁面。 我們之中的大多數人所運行的網站并不一定都有數據庫支持。我們的網站大多數由靜態(tài)頁面構成,然后用PHP在這里、那里加上一些動態(tài)功能,比如搜索引擎、反饋表單等。那么,如何在這種網站上應用模板呢? 最簡單的方法是為每一個頁面復制一份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代碼。 靜態(tài)網站的模板框架 首先,我們象前面一樣為所有的頁面公用元素以及頁面整體布局編寫模板文件;然后從所有的頁面刪除公共部分,只留下頁面內容;接下來再在每個頁面中加上三行PHP代碼,如下所示: . 代碼如下: <?php <!-- home.php --> <?php require('prepend.php'); ?> <?php pageStart('Home'); ?> <h1>你好</h1> <p>歡迎訪問</p> <img src="demo.jpg"> <p>希望你能夠喜歡本網站</p> <?php pageFinish(); ?> ?> 這種方法基本上解決了前面提到的各種問題?,F在文件里只有三行PHP代碼,而且沒有任何一行代碼直接涉及到模板,因此要改動這些代碼的可能性極小。此外,由于HTML內容位于PHP標記之外,所以也不存在特殊字符的處理問題。我們可以很容易地將這三行PHP代碼加入到所有靜態(tài)HTML頁面中。 require函數引入了一個PHP文件,這個文件包含了所有必需的與模板相關的PHP代碼。其中pageStart函數設置模板對象以及頁面標題,pageFinish函數解析模板然后生成結果發(fā)送給瀏覽器。 這是如何實現的呢?為什么在調用pageFinish函數之前文件中的HTML不會發(fā)送給瀏覽器?答案就在于PHP 4的一個新功能,這個功能允許把輸出到瀏覽器的內容截獲到緩沖區(qū)之中。讓我們來看看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函數首先創(chuàng)建并設置了一個模板實例,然后啟用輸出緩存。此后,所有來自頁面本身的HTML內容都將進入緩存。pageFinish函數取出緩存中的內容,然后在模板對象中指定這些內容,最后解析模板并輸出完成后的頁面。 這就是整個模板框架全部的工作過程了。首先編寫包含了網站各個頁面公共元素的模板,然后從所有頁面中刪除全部公共的頁面布局代碼,代之以三行永遠無需改動的PHP代碼;再把FastTemplate類文件和prepend.php加入到包含路徑,這樣你就得到了一個頁面布局可以集中控制的網站,它有著更好的可靠性和可維護性,而且網站級的大范圍修改也變得相當容易。 本文下載包包含 了一個可運行的示例網站,它的代碼注釋要比前面的代碼注釋更詳細一些。FastTemplate類可以在http://www.thewebmasters.net/找到,最新的版本號是1.1.0,那里還有一個用于保證該類在PHP 4中正確運行的小補丁。本文下載代碼中的類已經經過該補丁的修正。 PHP簡易生成靜態(tài)頁面 . 代碼如下: <?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">發(fā)布時間</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 簡易動態(tài)添加生成靜態(tài)新聞頁面 # # 表的結構 `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生成靜態(tài)網頁的兩個函數 在最近幾年,萬維網(也稱環(huán)球信息網,即WWW)不斷改變信息處理技術的面貌。WEB已經快速地成為一種有效的媒介,并適合人們和商業(yè)溝通和協(xié)作。幾乎所有的信息技術領域都普遍受到WEB的影響。Web訪問帶來更多用戶和更多數據,這意味著給服務器和數據庫更多壓力和最終用戶得到越來越慢的響應速度。與不斷靠增加CPU,磁盤驅動器及內存來跟上這種增長的需求相比, WEB動態(tài)網頁面靜態(tài)化應該是一個更實用,更經濟的選擇。 用PHP實現WEB動態(tài)網頁靜態(tài)化的具體實現函數如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〉"; } 這個函數是實現靜態(tài)化的關鍵,即PHP動態(tài)頁面程序不是被送到瀏覽器中,而是輸入到名為$filename的文件中去(如圖2)。兩個參數中$program是PHP動態(tài)頁面程序,$filename是生成的靜態(tài)頁面的名字(可根據需要自己制定命名規(guī)則,這一點很重要,見下文),/usr/local/php4/bin/php是PHP中具有把程序輸入文件功能的部分,System是PHP中執(zhí)行外部命令的函數。我們還可以看出所有生成動態(tài)頁面的php程序需放在/php/目錄下,所有新產生的靜態(tài)頁面則會出現在/static_html/目錄下(這些路徑可以根據具體需要設置)。 下面讓我們舉個具體例子,看一下college_static.php的靜態(tài)頁面是怎樣生成的。 . 代碼如下: 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經過靜態(tài)化,變成了33個靜態(tài)頁面college.static0.html~college.static33.html,其中$filename會隨著$I的變化而變化。當然也可以從數據庫中直接取值,來控制生成的靜態(tài)頁面的個數和名字,其他程序對生成的靜態(tài)頁面的調用應和靜態(tài)頁面的命名規(guī)則一致。 該文章在 2012/9/27 10:10:56 編輯過 |
關鍵字查詢
相關文章
正在查詢... |