CGI 程式寫法說明
原作者是誰, 我已不知道了, CGI 中的程式我修改過, 可能與本文中的些許不同, 但本篇文章的版權屬原作者的
本 文 目 錄
1.何謂CGI程式 ?
2.如何使用CGI程式呢 ?
3.用什麼語言來撰寫CGI程式呢 ?
4.第一個簡易CGI程式寫作:現在幾點了???
5.第二個CGI程式寫作:寫什麼就秀什麼???
6.第三個CGI程式寫作:酸甜苦辣留言版???
7.第四個CGI程式寫作:讀者意見調查表???
8.CGI程式之 Q & A
9.CGI實驗室
<a href="http://電腦/目錄/CGI程式名稱">敘述</a>
的方式來取得資源.
------> date <------ #!/bin/sh # 第一行的 #! 是 Unix shell script 的固定寫法 # 其後的 /bin/sh 是說這個CGI程式是在 /bin/sh 這個shell下執行 # 第二行後以 # 開頭的行,皆是當作註解使用 echo Content-type: text/plain echo # 上面這兩行是固定要寫的 # 事實上,經測試 echo Content-type: text/plain 這一行亦可省略 # 但是 echo 這一行一定要存在 echo -n '現在時間是 : ' # 顯示 '現在時間是 : ' 這段文字 # -n 參數表示印完文字後不換行 /bin/date # 執行 Unix 中 date 的指令 --------------------看看 date 這個CGI程式的執行結果吧!
怎麼樣!有趣吧!接下來再看一個例子.
------> print_input <------
#!/bin/sh
echo Content-type: text/html
echo
if [ $# = 0 ]; then
# 在 shell script 中 $# 代表傳到本程式的所有引數個數
# 當呼叫此程式時如未給任何參數, 則 $# = 0
# 下面這一段有特別的技巧, 叫做"行中的輸入重定向"
# 如果字串' << '在一命令之後,如 command << word
# 則 shell 會用其後的輸入行當作 command 命令的標準輸入,
# 直到碰到一行內只有字串 word 才停止.
# 下列幾行就是將 <TITLE> .......EOM 間的資料傳給 cat 命令
# 結果就是將這幾行字顯示在螢幕上.
cat << EOM
<TITLE>秀字程式</TITLE>
<H1>秀字程式</H1>
<ISINDEX>
您想印出"什麼東東",就在方格內輸入"什麼東東"
EOM
# <ISINDEX> 會產生一個輸入方格,讓您輸入任何東西
# 但是程式要在完全執行完畢後, 才讓您輸入東東( 特別注意這點 )
# 當您按下<Enter>時, 就會將輸入的資料當作本程式的引數
# 重新執行本程式.
#
# 在 shell script 中有幾個特別的參數
# 1. $# : 所有引數的個數
# 2. $0 : 目前這個程式的名稱
# 3. $1,$2,.. : 位置參數, 也就是第一個引數,第二個引數,..
# 4. $* : 所有的引數, 也就是 $* = $1 $2 ...
else
# 以下這一段是有輸入引數時才執行的, 也就是您在輸入方格
# 按下<Enter>後,再次執行本程式時才動作
# 請注意下面幾行的寫法和 HTML 文件的寫法完全相同, 只是都被包含在" "之間
# 並且都是用 echo 來顯示
echo "<pre>"
echo $*
echo "<hr>"
echo "<a href="/cgi-bin/print_input"><img src="/image/leftenter.gif">回秀字程式</a>"
echo "</pre>"
fi
---------------------------看看 print_input 這個CGI程式的執行結果吧!
哈哈哈!告訴您一個壞消息,如果您未輸入任何東東,就按下<Enter>
賓果!恭喜您得到一個"應用程式錯誤"的大獎.
好強的您如果想要做到盡善盡美,下一個例子千萬不可錯過喔!
首先,看看下面這個 HTML 文章(
注意:不是CGI程式喔!)
note_board.html 內容如下:
------> note_board.html <------
<html>
<title>酸 甜 苦 辣 留 言 版</title>
<body>
<h1>酸 甜 苦 辣 留 言 版</h1>
<hr>
當您看完了筆者的這一點點的心得後,<br>
相信您也有話要說,<br>
別客氣, 通通寫在留言版上,<br>
我會一一參考改進,<br>
謝謝<p>
<form method=post action="/cgi-bin/note_board">
<pre>
您的大名 : <input name="visitor" size=42>
標 題 : <input name="subject" size=42>
</pre>
留言版很大, 不要浪費了, 想寫什麼就寫什麼, 歡喜就好!
<textarea name="comments" rows=15 cols=60>留言:</textarea><p>
<input type="submit" value="8-) 哈哈哈 確定留言!!!">
<input type="reset" value="8-< 寫錯了 擦掉重來!!!">
</form>
</body>
</html>
------------------------------上面這一部份不是筆者所要介紹的, 只是要當作下面
CGI程式的輸入界面而已. 請您注意一下<form ... >這一行的 "/cgi-bin/note_board",
這才是我所要介紹的CGI程式.
當您看完了筆者的這一點點的心得後,
相信您也有話要說,
別客氣, 通通寫在留言版上,
我會一一參考改進,
謝謝
或許您會問當我已經寫好了, 要怎麼樣才能送出去呢? 其實很簡單, 您只要按下 "8-)哈哈哈 確定留言!!!" 這個按鈕, 就可以了.
當您按下按鈕, 程式便將所有資料傳給 "/cgi-bin/note_board"
這個程式.
傳送的格式如下:
visitor=JoJo&subject=Just+test&comments=%AF%64%A8%A5%3A........
您可以清楚的看到下面的幾點:
a) 程式傳給 "/cgi-bin/note_board" 的資料只有一項, 就是
"visitor..." 這一項.
b) 變數的名稱(visitor,subject,comments)及出現順序, 皆與 note_board.html
中的一樣.
c) 變數間以 "&" 符號互相隔開.
d) 變數名稱和輸入變數值以 "=" 符號互相隔開.
e) 大小寫英文字母,數字,某些符號可以正確無誤的傳送.
f) 空白以 "+" 來代表. 其他符號以 "%符號的ASCII值"
來代表. 例如: ":"以"%3A"來代表.
g) 中文字則以兩位元的 BIG5 碼表示. 例如: "留"這個字的 BIG5
碼為 af64, 以"%AF%64"來表示.
看到這裡, 想必您已經猜到 "/cgi-bin/note_board" 這個CGI程式的作用就是讀取傳送到的資料, 將資料還原成原來的樣子, 並依照我們的需求來處理.
note_board 程式內容如下:
------> note_board <------ #!/bin/sh echo Content-type: text/html echo read data echo $data > /tmp/data.tmp # 讀取資料並放入 /tmp/data.tmp 中 visitor=`cut -d"&" -f1,1 /tmp/data.tmp` subject=`cut -d"&" -f2,2 /tmp/data.tmp` comments=`cut -d"&" -f3,3 /tmp/data.tmp` # 因變數間以 "&" 相互隔開, 故利用 cut 來得到單一變數. echo $visitor > /tmp/data.tmp visitor=`cut -d"=" -f2,2 /tmp/data.tmp` echo $subject > /tmp/data.tmp subject=`cut -d"=" -f2,2 /tmp/data.tmp` echo $comments > /tmp/data.tmp comments=`cut -d"=" -f2,2 /tmp/data.tmp` # 因變數名稱與輸入變數值以 "=" 隔開, 故利用 cut 來得到輸入變數值. rm /tmp/data.tmp # 刪除暫存資料檔 # 至此, 我們已經得到每個變數的輸入值 # 以下便是依照個人需要來處理變數. echo "Visitor : $visitor" >> /tmp/note echo "Subject : $subject" >> /tmp/note echo "Comments : $comments" >> /tmp/note echo "---------------------------------------------------" >> /tmp/note echo "<pre>" echo "我已經記下您的留言, " echo "如果有需要, 我會儘快給您回信, " echo "謝謝.
" echo "<hr>" echo "<a href="http://alpha.secc.fju.edu.tw/~macgyver/skill/cgi/tools_text.html#formend"><img src="/image/rightenter.gif"></a> 回CGI程式寫法說明." echo "</pre>" ------------------------------------------- 看看 note_board 這個CGI程式的執行結果吧!
仔細的您, 在看完上面的程式, 可能會有一個小小的疑問, 我們好像還沒有將被更改的中文字, 符號 及空白恢復原狀? 沒錯, 您是對的. 到目前為止, 我們只是取出變數值, 並依照需要予以處理而已. 您或許會問為什麼我們沒有處理這些字碼的轉換的呢? 原因有二, 一則字碼轉換程式可以適用於每個使用 FORM , INPUT 的CGI程式, 為了使用上的方便, 所以寫成另外一個轉換程式; 二則如果每次有新的留言, 就執行轉換程式一遍, 只是徒然浪費時間罷了. 基於上述兩個理由, 筆者另外寫了一個轉換程式, 只有當您想看留言的內容時, 才執行轉換程式, 這樣就能達到省時又省力的目的.
筆者使用 Unix Shell Script ( Bourne Shell ) 寫了一個轉換程式,
格式如下:
trans (輸入檔) ==> 直接輸出到螢幕 或 trans (輸入檔) > (輸出檔) ==> 輸出到目的檔案 以"酸甜苦辣留言版"這個CGI程 式而言, 若我想看留言的內容, 則需做下列的轉換工作.
trans /tmp/note > Object_file
Object_file 就是所有留言的資料, 筆者只要看這個檔案, 就可以知道您的寶貴意見囉!
備註:目前有些CGI程式使用 perl 這個 shell
來處理字串有關的部份, 聽說 prel 在處理字串方面的能力很強,
但是這個程
式並非 Unix 的內建 shell , 需要另外安裝, 除此之外, 還得學習 prel
的語法, 筆者私下認為倒不如使用 Unix 的 shell script
來處理相關部份.
如果您想要筆者寫的這個轉換程式, 請在 trans.Z 這個字上按一下, 就可以拿到手啦!
拿到手時, 然後在 Unix 下, 執行下面的敘述, 就可以得到 trans 這個檔案了.
reader 內容如下:
------> reader <------ #!/bin/sh echo Content-type: text/html echo if [ $# != 0 ] then # 當呼叫 reader 時, 若有給定參數(也就是輸入資料), 則會執行下面的程式段. # 這部份程式段的功能在將讀者輸入的個人資料, 和調查結果分別取出. # 然後加入讀者意見調查資料庫中. read data name=`echo $data | cut -d"&" -f1,1 | cut -d"=" -f2,2 | /home/User/WWW/cer n_httpd_3.0/docs/work/trans | cut -c1-6` # 將名字由 data 中取出, 經過 trans 轉換成中文, 然後只取前 6 # 個字母(三個中文字)來顯示. sex=`echo $data | cut -d"&" -f2,2 | cut -d"=" -f2,2` # 取出性別的輸入資料 unit1=`echo $data | grep "unit1" | /usr/ucb/wc -l` unit2=`echo $data | grep "unit2" | /usr/ucb/wc -l` unit3=`echo $data | grep "unit3" | /usr/ucb/wc -l` unit4=`echo $data | grep "unit4" | /usr/ucb/wc -l` value1=`echo $data | grep "value1" | /usr/ucb/wc -l` value2=`echo $data | grep "value2" | /usr/ucb/wc -l` value3=`echo $data | grep "value3" | /usr/ucb/wc -l` value4=`echo $data | grep "value4" | /usr/ucb/wc -l` value5=`echo $data | grep "value5" | /usr/ucb/wc -l` # 分別設定 unit1-4 , value1-5 之值. # 1 : 表示得到一票 0 : 表示沒有. # unit1-4 分別表示四個 CGI 單元得票與否. # value1-5 分別表示您對本文的評價等級. echo "<pre>" echo $name'~'$sex'~'$unit1$unit2$unit3$unit4'~'$value1$value2$value3$value4 $value5 | tr ~ '\11' >> /home/User/WWW/cern_httpd_3.0/docs/work/reader.db echo "</pre>" # 這三行是把讀者的輸入資料, 加入讀者意見調查資料庫中. fi # cat << EOM # ... anything ... # EOM # 這個結構, 我們在”秀字程式”中曾經解說過. # 如果您忘記了, 麻煩您回頭看一下吧! # 下面的內容, 就是使用者所看到的表格. cat << EOM <title>讀 者 意 見 調 查 表</title> <center><h1>讀 者 意 見 調 查 表</h1></center> <hr> <form method=post action="/cgi-bin/reader??"> <dl> <dt>◎ 您的基本資料: <p> <dd>您的大名:<input name="name" size=16> <dd>您的性別:<input type="radio" name="sex" value="man" checked> ♂ <input type="radio" name="sex" value="woman"> ♀ <p> <dt>◎ 您最喜歡的單元:(複選) <p> <dd><input type="checkbox" name="unit" value="unit1">現在幾點了??? <dd><input type="checkbox" name="unit" value="unit2">寫什麼就秀什麼??? <dd><input type="checkbox" name="unit" value="unit3">酸甜苦辣留言版??? <dd><input type="checkbox" name="unit" value="unit4">讀者意見調查表??? <p><p> <dt>◎ 您對於”CGI程式寫法說明”的評價: <p> <dd><select name="value" size=1> <option value="value1">好極了 <option value="value2"> 好 <option value="value3">普 通 <option value="value4"> 爛 <option value="value5">爛透了 </select> <dt><hr> <dd><input type="reset" value="重寫一張"><input type="submit" value="投進票箱"> <dt><hr> </dl> </form> <pre> <h3>目前意見調查情形如下:</h3> 單單單單 好 普 爛 姓 名 姓 別 元元元元 極好 爛透 一二三四 了 通 了 </pre> EOM echo "<pre>" cat /home/User/WWW/cern_httpd_3.0/docs/work/reader.db echo "</pre>" # 上面這幾行就是列印選項說明及讀者調查資料庫的資料. echo "<hr>" ----------------------------------------------------------看看 reader 這個CGI程式的執行結果吧!
這個CGI程式的 key point 有兩點:
首先, 請注意程式中如下的這一行
<form method=post action="/cgi-bin/reader??">
︿︿︿︿
看到了嗎?有兩個奇怪的”?”在CGI程式 reader
的後面.
經過筆者個人的試驗, 這兩個問號( 三個問號也可以 )的作用是把讀者輸入的資料傳給自己
(也就是 reader), 如果不加上這兩個問號, 則只是執行 reader 而已,
並不將讀者輸入的資料傳入.
看到這裡, 您當會發現這個CGI程式執行時, 可能有兩種情況, 不帶參數和帶參數兩種. 不帶參數的情況發生在 html 直接呼叫 reader . 而帶參數的情況發生在由 FORM 呼叫 reader 時, 也就是讀者輸入資料, 然後按下 submit 或 return 時.
由於上述兩種執行情況的不同, 才產生第二個 key point , 也就是
if [ $# != 0 ]
then
...
fi這個 if ... else ... fi 的結構. 當執行 reader 且沒有參數 ( #$ =0 ) 時, 就會略過這段程
式. 如果附帶有參數 ( $# != 0 ) 時, 則會執行這段程式碼. 而這段程式就是負責處理讀者的輸入資料,
並將該資料加入讀者意見調查資料庫中.
讀者意見調查資料庫( reader.db )的格式如下, 提供您參考看看:
王照坤 man 0 0 0 1 1 0 0 0 0 Richar man 1 1 1 1 0 1 0 0 0 ...... ... ....... .........
哈哈哈!恭喜您已經練成乾坤大挪移第四層的功力, 接下來...休息一下吧!
如果您有任何意見或指教, 您可以寫在"酸甜苦辣留言版", 也可以直接寫信給我.
E-mail : macgyver@alpha.secc.fju.edu.tw
如果您還有時間, 歡迎您來 輔仁大學理工學院電算中心全球資訊網逛逛.
並提供您的寶貴意見, 讓我們作為改進之參考.
謝謝