?
このドキュメントでは、 php中國語ネットマニュアル リリース
你可以用Ruby輕松的編寫CGI腳本,為了讓Ruby腳本產(chǎn)生HTML輸出,你只需要這樣做:
#!/usr/bin/env?ruby print?"HTTP/1.0?200?OK\r\n" print?"Content-type:?text/html\r\n\r\n" print?"<html><body>Hello?World!</body></html>\r\n" |
你可以用Ruby的正則表達(dá)式來解析輸入字符串,查詢環(huán)境變量,檢查標(biāo)記,填充模板,轉(zhuǎn)義(escape )特殊字符,格式化HTML,然后輸出。
或者,你可以用類CGI。
類CGI主要來幫助你更方便的編寫CGI腳本,使用它,你可以操縱表單(form),cookies和環(huán)境變量,維護(hù)有狀態(tài)的session等等。關(guān)于它的文檔在第497頁,但是我們在這里要先看一下它大體的功能。
?
當(dāng)處理URL和HTML的時候,我們必須注意對一些特殊字符的引用。比如,一個斜線 (``/'') 在URL里有特殊意義,如果它不是URL的路徑名稱的一部分,那么它必須被轉(zhuǎn)義(escaped)。也就是說,它在URL中將被轉(zhuǎn)換為 ``%2F
'',而且反過來你要想使用它,必須把它再轉(zhuǎn)換為斜線。空格和and符號("&")也是特殊字符。為了處理這樣的情況,CGI提供了方法 CGI.escape
和CGI.unescape
。
require?'cgi' puts?CGI.escape(?"Nicholas?Payton/Trumpet?&?Flugel?Horn"?) |
Nicholas+Payton%2FTrumpet+%26+Flugel+Horn |
類似的,你也許需要對HTML中的特殊字符進(jìn)行轉(zhuǎn)義(escape ):
require?'cgi' puts?CGI.escapeHTML(?'<a?href="/mp3">Click?Here</a>'?) |
<a?href="/mp3">Click?Here</a> |
而且,你也可以只對HTML的一部分標(biāo)記進(jìn)行轉(zhuǎn)義,而不是全部:
require?'cgi' puts?CGI.escapeElement('<hr><a?href="/mp3">Click?Here</a><br>','A') |
<hr><a?href="/mp3">Click?Here</a><br> |
這里又有A標(biāo)記被轉(zhuǎn)義了,其它標(biāo)記都沒有變化。
每個這樣的轉(zhuǎn)義方法都有一個un-開頭的版本,來恢復(fù)這個轉(zhuǎn)義之前的字符串。
使用CGI類你有兩種方法訪問HTML傳過來的參數(shù)。比如我們有一個URL/cgi-bin/lookup?player=Miles%20Davis&year=1958
,你可以用CGI#[ ]方法直接訪問player和year變量:
require?'cgi' | ||
cgi?=?CGI.new | ||
cgi['player'] |
? |
["Miles?Davis"] |
cgi['year'] |
? |
["1958"] |
或者,你可以把所有參數(shù)放入一個Hash中,再從這個哈希查詢參數(shù)。
require?'cgi' | ||
cgi?=?CGI.new | ||
h?=?cgi.params | ||
h['player'] |
? |
["Miles?Davis"] |
CGI類包含了很多產(chǎn)生HTML的方法,每個HTML標(biāo)記都有一個方法。為了使用這些方法,你首先要創(chuàng)建一個CGI對象,這可以通過CGI.new
方法。這個方法可以接收一個參數(shù)表示HTML的級別。比如,我們這里用了html3。
為了使得這些標(biāo)記嵌套方便,這些方法都接受一個block作為來處理內(nèi)容,這個block返回一個字符串,這也是這個tag的內(nèi)容。比如下面的例子,我們加入了一些換行是為了能適應(yīng)屏幕,能使得它被很好的顯示而已。
require?"cgi" cgi?=?CGI.new("html3")??#?add?HTML?generation?methods cgi.out{ ??cgi.html{ ????cgi.head{?"\n"+cgi.title{"This?Is?a?Test"}?}?+ ????cgi.body{?"\n"+ ??????cgi.form{"\n"+ ????????cgi.hr?+ ????????cgi.h1?{?"A?Form:?"?}?+?"\n"+ ????????cgi.textarea("get_text")?+"\n"+ ????????cgi.br?+ ????????cgi.submit ??????} ????} ??} } |
Content-Type:?text/html Content-Length:?302 <!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?3.2?Final//EN"><HTML><HEAD> <TITLE>This?Is?a?Test</TITLE></HEAD><body> <FORM?METHOD="post"?ENCTYPE="application/x-www-form-urlencoded"> <HR><H1>A?Form:?</H1> <TEXTAREA?NAME="get_text"?ROWS="10"?COLS="70"></TEXTAREA> <BR><INPUT?TYPE="submit"></FORM></body></HTML> |
這段代碼將產(chǎn)生一個HTML文檔,主題(title)為“This?Is?a?Test”,然后一個水平線,然后是一個header,一個測試的輸入框,一個提交按鈕。當(dāng)接收到這個提交的頁面,你會得到一個變量名為get_text,其值為你輸入的文本。
你可以通過使用cookies在客戶機(jī)上存放各種有用的信息,你可以創(chuàng)建一個有名字的cookie,并且設(shè)定一個指定的值。為了將這個cookie發(fā)送到瀏覽器,你需要在CGI#out中設(shè)置cookie 頭(header)。
require?"cgi" cookie?=?CGI::Cookie.new("rubyweb",?"CustID=123",?"Part=ABC"); cgi?=?CGI.new("html3") cgi.out(?"cookie"?=>?[cookie]?){ ??cgi.html{ ????"\nHTML?content?here" ??} } |
Content-Type:?text/html Content-Length:?86 Set-Cookie:?rubyweb=CustID%3D123&Part%3DABC;?path= <!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?3.2?Final//EN"><HTML> HTML?content?here</HTML> |
當(dāng)用戶下次訪問這個頁面時,你可以取得cookie CustID
和Part
,然后將它們顯示在HTML輸出中。
require?"cgi" cgi?=?CGI.new("html3") cgi.out{ ??cgi.html{ ????cgi.pre{ ??????cookie?=?cgi.cookies["rubyweb"] ????????"\nCookies?are\n"?+?cookie.value.join("\n") ????} ??} } |
Content-Type:?text/html Content-Length:?111 <!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?3.2?Final//EN"><HTML><PRE> Cookies?are CustID=123 Part=ABC</PRE></HTML> |
cookies需要我們進(jìn)行一些人為處理后才變得有用,我們真正需要的是一個session:web客戶端的持久性的狀態(tài)。session在Ruby中用 CGI::Session
處理,它也使用了cookie,但是提供了一個高層次的接口。
require?"cgi" require?"cgi/session" cgi?=?CGI.new("html3") sess?=?CGI::Session.new(?cgi,?"session_key"?=>?"rubyweb", ??????????????????????????"session_id"??=>?"9650", ??????????????????????????"new_session"?=>?true, ??????????????????????????"prefix"?=>?"web-session.") sess["CustID"]?=?123 sess["Part"]?=?"ABC" cgi.out{ ??cgi.html{ ????"\nHTML?content?here" ??} } |
這將給用戶rubyweb發(fā)送一個cookie,它的值為9650。它也會在服務(wù)器的上建立一個文件$TMP/web-session.9650
,以“鍵-值”(key-value)的方式保存著CustID和Part的值。
當(dāng)這個用戶又訪問這個網(wǎng)站時,你需要一個參數(shù)指明session id。在這個例子里應(yīng)該是rubyweb=9650
,然后,你就可以取得所有和這個sesion相關(guān)的數(shù)據(jù)了。
require?"cgi" require?"cgi/session" cgi?=?CGI.new("html3") sess?=?CGI::Session.new(?cgi,?"session_key"?=>?"rubyweb", ???????????????????????????????"prefix"?=>?"web-session.") cgi.out{ ??cgi.html{ ????"\nCustomer?#{sess['CustID']}?orders?an?#{sess['Part']}" ??} } |
到目前為止我們已經(jīng)看過了用Ruby創(chuàng)建HTML文件和顯示它,下面我們來看看如何將Ruby嵌入HTML文檔中。
有好幾個包支持我們將Ruby嵌入其它文檔中,特別是HTML頁面,一般來說,這叫做eRuby,它的實現(xiàn)也有好幾種,比如eruby和erb。下面的部分將介紹eruby。
將Ruby腳本嵌入HTML非常有用,我們不僅能像ASP,JSP,PHP一樣使用它,而且還能發(fā)揮Ruby的力量。
eruby
簡單來說就像一個過濾器,對于輸入的文件中的普通HTML內(nèi)容,它將不會做什么處理,而對下面的格式的代碼進(jìn)行特殊處理:
表達(dá)式 | 意義 | |||||||
<% ruby code %> |
將定界符內(nèi)的Ruby代碼轉(zhuǎn)換為它的結(jié)果輸出 | |||||||
<%= ruby expression %> |
輸出這個表達(dá)式的值到HTML中 | |||||||
<%# ruby code %> |
代碼注釋,這些內(nèi)容將被忽略。對測試來說可能有用。 | |||||||
![]() |
調(diào)用eruby的方法如下:
eruby [ options ] [ document ] |
如果document忽略,則eruby將從標(biāo)準(zhǔn)輸入讀取。eruby的命令行參數(shù)如下:
|
讓我們來看一些簡單的例子,假如我們給eruby運(yùn)行時候的輸入為下面的內(nèi)容:
This?text?is?<%?a?=?100;?puts?"#{a}%?Live!"?%> |
eruby
將把<%和%>之間的Ruby代碼換成它執(zhí)行后的值然后顯示出來。This?text?is?100%?Live! |
使用 <%= 的形式,直接將后面的表達(dá)式的值輸出,比如,我們的輸入如下:
<%a?=?100%>This?text?is?almost?<%=a%>?degrees!?Cool! |
This?text?is?almost?100?degrees!?Cool! |
當(dāng)然,你也可以將Ruby嵌入更復(fù)雜的文檔,比如HTML。
<!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01//EN"> <html> <head> <title>eruby?example</title> </head> <body> <h1>Enumeration</h1> <ul> <%(1..10).each?do|i|%> ??<li>number?<%=i%></li> <%end%> </ul> <h1>Environment?variables</h1> <table> <%ENV.keys.sort.each?do?|key|%> ??<tr> ????<th><%=key%></th><td><%=ENV[key]%></td> ??</tr> <%end%> </table> </body> </html> |
你可以安裝一個使用eRuby的Apache服務(wù)器來自動解析嵌入Ruby的文檔,就像PHP那樣。你可以將嵌入Ruby的文檔命名為以`.rhtml
'' 為后綴,然后設(shè)置web服務(wù)器來調(diào)用eruby來解析這些文件輸出想要的HTML。
為了在Apache中使用eruby,需要以下幾步。
eruby
程序拷貝到 cgi-bin
目錄
httpd.conf
文件中增加如下兩行:
AddType?application/x-httpd-eruby?.rhtml Action?application/x-httpd-eruby?/cgi-bin/eruby |
DirectoryIndex
指令中加入 index.rhtml
,這樣,如果你的目錄下面如果沒有index.html文件,則就會使用index.rhtml文件作為index頁。比如下面的例子
DirectoryIndex?index.html?index.shtml?index.rhtml |
當(dāng)然,你也可以用一個作用于一個全站點范圍的Ruby腳本
Of course, you could also simply use a site-wide Ruby script as well.DirectoryIndex?index.html?index.shtml?/cgi-bin/index.rb |
就是如此,你可以在HTML文檔中加入嵌入的Ruby腳本來動態(tài)地創(chuàng)建表單和內(nèi)容。但也請你閱讀一下從497頁開始的CGI庫。
你可以使用Ruby為web編寫CGI程序,但是,如同其它CGI程序一樣,默認(rèn)得設(shè)置下,對每個cgi頁面的請求都將產(chǎn)生一個新的Ruby進(jìn)程,這將占用服務(wù)器很多的資源,而且容易引起性能的下降。Apache web服務(wù)器通過使用可裝載的模塊來解決這個問題。
一般來說,這些模塊都會動態(tài)的被載入,而且會成為Web服務(wù)器進(jìn)程的一部分,也就是說不需要每次有CGI請求進(jìn)來都產(chǎn)生一個Ruby解釋器程序,Web服務(wù)器就充當(dāng)了解釋器的角色。所以我們會用到mod_ruby,它會將Ruby解釋器連接(links)到Web服務(wù)器,關(guān)于它的具體信息可以看它的發(fā)布程序附帶的README文件。
一旦你安裝配置好之后,你就可以像原來一樣運(yùn)行Ruby腳本,不同的是現(xiàn)在地速度應(yīng)該是快很多了。