GB | BIG5
|
| 首頁 > 編程技術 > Perl > 正文 |
 |
| Perl 語言全面編譯(四) |
| http://www.ccw.com.cn 天水-S.Tanshuai (2001-04-19 15:11:45) |
第六節 HTML模板編程方式真正的WEB程序
什是真正的程序(Program)?我們平時使用ASP、PHP這些都不屬程序,它們只是一種頁(Page),動態頁面(Dynamic Page),但是我們一般稱作頁面編程(Web Programming),但這種說法不確切(並非不正確)。程序就是程序,並非所有的語言都叫做程序或編程語言。很多權威的書籍、文章和網站(例如:Yahoo!)都沒有將ASP、PHP當作程序(編程語言)來解釋。ASP是一種語言介質,PHP在Yahoo的定義頁只是類似SSI。他們說要做的東西頂多就是一個“台(服務器端)的HTML(或者說是Script)”,可以想象,頁(Page)和程序(Program)的差異,至少可以說頁是由程序來解析輸出結果的。那也就是說,頁想要做的事情比程序要局限得多。PHP不是一種程序,如果用ASP或PHP做一個Http服務器,你會有什感覺?你見過嗎?你見過ASP、PHP做的非Web“程序”嗎?我想你沒有見過。你相信用ASP、PHP編制出類似Windows的圖形(GUI)界面程序嗎?那是一種什感覺呢?所以,做程序和頁面是兩種不同的概念,在國內不知道是翻譯的時候錯誤,還是大家都是這樣理解的。
如果你要寫一個Web頁,做一些小動作,用ASP、PHP、ePerl等未嘗不可。但是它不是來給你做大宗Web項目或者軟件而設計的。至少我是這樣認為。而且我覺得Perl目前在程序中直接使用HTML是一種不好的習慣或者行為。它將增加維護成本,降低工作效率等諸多不便因素。其實我覺得外制式的模板方式的HTML套入法是適合時代潮流以及未來軟件升級擴展的。至少可以讓客戶在不觸及程序核心的前提下,隨意修改界面,可以得到個性化、特性化的設置未來趨勢。而且我們可以降低很大維護的成本,同時某些不變的(諸如:版權、聲明、標示)內容仍然可以使用內置式或者在套入模板的過程中進行相應修改等。如果你真的不喜歡他人修改模板,那你可以使用加密方式,對模板文件進行加密,可以達到程序操作目的,和降低維護成本,而禁止他人修改的目的(推薦使用:Crypt::RC4)。
本章將會著重講述在Perl程序中(不但只是為了編譯Perl)使用套入法,套入模板HTML,並且進行靈活的HTML操作。
以下是標準的內置式和外制式的HTML操作:
內置式HTML程序:
#!perl
$Var="HELLO WORLD";
print <
Content-type: text/html
$Var
HTML
exit;
外置式HTML程序:
#!perl
$Var="HELLO WORLD";
open (HTML,"../HelloWorld.html");#打開HelloWorld.html文件
@HTML=;
close (HTML);
print Content-type :text/html ;
foreach (@HTML) {#循環
$_ =~ s/\*Var/$Var/g;#替換Hellworld.html 文件中*Var的內容為變量$Var的內容
print "$_";#輸出
}
exit;
外置式HTML文件 HellWorld.html:
*Var
上面的例子都是現實操作中廣泛(流行)用法,大家可能感覺到外置式有些復雜,其實不然,你只要把它做成一個函數或者對象就相當容易了。
關鍵問題在,變量的替換,若使用上面的方法,有些不妥,因為默寫模板頁面不一定是適合的那些變量,如果你把所有的變量都放在foreach裡面,那勢必對程序運行資源造成極大浪費,而且得不償失,影響效率。這樣做成一個函數或者對象,對會有不通用的問題。
所以建立一個靈活的分析方法,對模板HTML處理提供良好的快捷的運作模式。
這個時候我們就要利用Perl強大的語法分析,來做一個自己的HTML語言分析語句了。這個語句看似簡單缺令人頭疼。
我們現在以“*”符號作為模板中的變量(類似Perl 中的$),這樣有助辨析。那我想要把所有以“*”開頭的變量,自動變換成程序內的對應變量,例如:要把*abc成為內部的$abc。一般情況我們需要逐個設置,這樣大大浪費了時間,我們現在需要做一個通用的方法,無論什的量都自動轉換。這個語法很簡單:
$_ =~ /\*(\w+)/;
看似簡單的一局話,卻有很大的作用,這句就是把以*開頭的字符的名找出來,但是有趣的是,你不需要進行太復雜的,只要遇到空格或者其它非標準字符,就會自動排除。
現在我們要把找到的字符名(即HTML的自定義變量)發給一個臨時變量中(該步驟可以不做):$tmp = $1 ;
現在要做的就是把這個*abc換成量$abc的值:
$_ =~ s/\*$tmp/$Html{"$tmp"}/g
這裡的$Html是散列變量(HASH),為了方便和容易理解,我在這裡採用HASH,這樣對應的$Html{‘abc’}就被提出來,換掉*abc了。
下面就是我做的模板套用函數與例子。
打開文件的函數RTF:
#!perl
sub RTF{
open(READTXTFILE,"$_[0]");
@readtxtfile=;
close(READTXTFILE);
return @readtxtfile;
}
分析模板的函數PHF:
#!perl
sub PHF {
my $file = "$_[0]";
@HtmlFileMessages=&RTF("$file");#Open File;
foreach (@HtmlFileMessages) {
$_ =~ /\*(\w+)/; #替換網頁的變量,批量處理,尋找“*
--------------------------------------------------------------------------------
第七節 聯合編譯以及實例
本章至關重要,你已經知道Perl的兩種最好的編譯方法。但是他們都有利弊,只要稍動腦筋,就可以實現“強強聯合”,這樣可以盡量避免那些缺憾。
聯合編譯的道理很簡單,但操作起來也不那樣一帆風順,其中有很多地方值得注意。聯合編譯主要有一個主程序和多個子程序(FILE)組成。它們之間是使用require函數連接。主程序只做連接等分析工作,子程序做細節工作,包括對象操作,模塊引用。我們採用PerlCC 翻譯C的方式來編譯主程序成為一個可以執行的文件,在把子程序用Bytecode方式編譯,這樣即可免去無法使用部分模塊的問題,也可以直接使用Perl程序,只要在主程序的前面定義一下模塊引用路徑,方法:
use lib ‘<路徑>’;
這樣就可以了,把那些需要調入的模塊,放在制定路徑中就好了。而且在CGI或者Socket的網絡編程和頁面編程中,使用該模是有助提高效率,降低資源佔用率。如果使用整體編譯方法,那每次啟動必然會耗費相當大的內存,同樣這個程序要重復關閉啟動,做Fast CGI也是相當不方便的,這也是Fast CGI在Perl中的最好的方法。根據不同的請求套入不同的子程序。
首先我們使用 cgi-lib.pl得去POST和GET數據(這個時候有些人會問,為什不使用cgi.pm,我不是不想用它,而是cgi.pm在perlcc的任何編譯模式都會有問題)
然根據不同的請求,我在這裡設置為action。
例如:
require “cgi-lib”;
if ($in{‘action’} eq “”) {
require “display.pl”;
&display;
exit;#可選
}elsif ($in{‘action’ }eq “love”) {
require “love.pl”;
&love;
exit;#可選
}
這樣是很好的。我們使用perlcc 標準編譯方法編譯它,然用-b模式編譯display.pl和love.pl。然把它們的名字改回.pl。
注意在使用perlcc編譯程序的時候,編譯出來的程序必須帶有應用程序擴展文件,如dll和so。因為你的程序還需它們支持,這個文件在Perl的解析軟件目錄下,例如perl5.6就是perl56.dll,必須把它拷貝到執行文件目錄地下。在Linux下是.so。你最好在一個沒有Perl 平台解析器的環境下進行測試,把那些需要使用的包也包括在裡面。即使是VC等軟件編譯出來的程序,都需要在純環境下測試,這是必要的。這樣就可以測試出程序的一些不必要的問題。
另外perlcc 的任何模式對語法都是很挑剔的,所以你最好使用比較正規的編寫方法,而且單個perl程序如果程序量太大,必須截取到另一個文件中,否則編譯容易出現內存溢出現象。
大家要知道如果你的子程序使用了ByteCode編譯,但是他人仍然可以把你的子程序改成源代碼形式,這樣就好像我說的會被套出很多量。最好的的方法,是採用ByteCode 編譯的程序寫入一個Auth認証函數。當然最保險的方法是使用文件內容驗証,但是效率影響,我認為不大必要。
主程序:
# !perl
require “cgi-lib”;
if ($in{‘action’} eq “”) {
auth (“display.pl”);
&display;
exit;#可選
}elsif ($in{‘action’ }eq “love”) {
auth (“love.pl”);
&love;
exit;#可選
}
sub auth {
require "$_[0] " ;
$auth = &check ;
if ($auth ne "checkabcdefg "){
exit ;
}
}
Display.pl
# !perl
sub check {
$check= "checkabcdefg " ;
return $check ;
}
sub display {
print "content-type :text/html \n\n" ;
print "hello baby " ;
}
上面是一種簡單的,不過也會造成一些問題,所以下面是一個麻煩(並非復雜)方法,但是很安全。
檢查編譯程序是否真實:
# !perl
open (FILE,"./print.pl");
@FILE=;
close (FILE);
foreach (@FILE) {
if ($_ =~/程序編譯的部分代碼/){
}else {exit ;}
}
首先把程序進行bytecode編譯,然截取部分獨特的其它程序沒有的代碼,放入其中,來檢查引入程序是否正確合法。
你可以把bytecode的程序改名成.dll等,這樣其它人就不知道是怎回事啦。
結束語
Perl是一個強大的而且是最早的解析性程序語言,它的編譯程序是B模塊,大家可以詳細常見,它有多種編譯方式,都是採用反向編譯(BackEnd)不同反編譯。所以經本上是不可能被反編譯。我認為本文對所有的Perl程序員都有很大的幫助。
Perl還有很多其它方式的編譯、加密方法,但是我覺得本文介紹的幾種方式都是最好的(兼容性和運行效率),有一些人,把寫的程序進行部分字符亂碼或者是取消縮近的書寫格式(把所有程序寫在一行上),我認為這些方法是“愚蠢的”,所以建議大家不要花那多時間去研究這些“無謂”的東西。
部分字符編碼例子原本:
# !perl
sub Hello {
$hello=abc ;
print $hello ;
}
&hello ;
部分字符編碼例子編碼
# !perl
sub adfjierei123489dkajd_dfefnkdj {
$iernvmdnvcjnaldffgh=abc;
print $iernvmdnvcjnaldffgh;
}
&adfjierei123489dkajd_dfefnkdj;
我希望通過本文促使Perl在國內的商業發展,也同樣加快了Perl技術在國內的發展速度。但是我仍然希望大家可以寫更多的公開源代碼的程序出來,這樣可以讓初學者有較快的提高速度。
如果你有任何問題和想法都可以通過電子郵件(tanshuai@BIGFOOT.COM, tanshuai@163.COM, tanshuai@TANSHUAI.NET)或者ICQ:25856530 OICQ:66552聯絡我,其它資料可以到我的網站查詢http://www.tanshuai.net http://www2.tanshuai.net (全文完)
(http://www.fanqiang.com)
進入【UNIX論壇】
|
|
| 相關文章 |
Perl 語言全面編譯(四) (2001-04-19 15:11:45) Perl 語言全面編譯(三) (2001-04-19 15:09:06) Perl 語言全面編譯(二) (2001-04-19 15:05:32) Perl 語言全面編譯(一) (2001-04-19 15:03:46)
|
|
|
|
 |
★ 樊強制作 歡迎分享 ★ |