當使用ASP編寫虛擬社群、網路購物等程式時,Application和Session物件具有舉足輕重的作用,能夠靈活合理地運用這兩
個物件是提高程式品質的關鍵。以下讓筆者根據自己在這方面的經驗,向大家深入介紹一下ASP的這兩個內建物件。
一、Application物件的成員概述
Application物件成員包括Application物件的集合、方法和事件。
⒈Application物件的集合
Contents集合:沒有使用<OBJECT>元素定義的儲存於Applicaiton物件中的所有變數的集合
StaticObjects:使用<OBJECT>元素定義的儲存於Application物件中的所有變數的集合
例:在default.asp中有如下賦值
application(a)=a
application(b)=128
application(c)=false
則有contents集合
application.contents(1)=a '也可寫為application.contents(a)=a
application.contents(2)=128 '也可寫為application.contents(b)=128
application.contents(3)=false '也可寫為application.contents(c)=false
在此筆者推薦你在呼叫時使用類別如application.contents(a)的方法,因為這樣比較為直觀,如果用序號來表示的話則
要考慮賦值的先後順序。
⒉Application物件的方法
Contents.Remove(變數名稱):從Application.Contents集合中刪除指定的變數
Contents.RemoveAll() :把Application.Contents集合中的所有變數刪除
Lock() :鎖定Application對象,使得只有當前的ASP頁對內容能進行訪問
Unlock() :解除對Application物件的鎖定
例:在default.asp中:
application(a)=a
application(b)=128
application(c)=false
response.write application.contents(1)&<br>
response.write application.contents(2)&<br>
response.write application.contents(3)&<br>
response.write After Remove b:
application.contents.remove(b)
response.write application.contents(1)&<br>
response.write application.contents(2)&<br>
執行結果:
a
128
False
After Remove b:
a
False
如果要刪除集合中所有變數用application.contents.removeall即可,至於Lock和Unlock方法在實際中常用到,讀
者也比較熟悉,在此就不在累贅。
⒊Application物件事件
OnStart:第一個存取伺服器的使用者第一次造訪某一頁面時發生
OnEnd :當最後一個使用者的會話已經結束並且該會話的OnEnd事件所有程式碼已經執行完畢後發生,或最後一個使用者訪問
伺服器一段時間(一般為20分鐘)後仍然沒有人訪問該伺服器產生。
想要定義application物件的OnStart和OnEnd事件裡做什麼需要將程式碼寫在Global.asa這個檔案裡(下文有舉例),並
且將該檔案放在網站的根目錄下(一般是Inetpubwwwroot)
二、Session對象的成員概述
Session物件的成員比Application物件多一項屬性,分別為:集合、屬性、方法、事件
⒈Session物件的集合
Contents :沒有使用<OBJECT>元素定義的儲存於特定Session物件的所有變數的集合。
StaticObject:使用<OBJECT>元素定義的、儲存於Session物件中的所有變數的集合。
例:在default.asp中有如下賦值
session(a)=a
session(b)=128
session(c)=false
則有contents集合
session.contents(1)=a '也可寫成session.contents(a)=a
session.contents(2)=128 '也可寫成session.contents(b)=128
session.contents(3)=false '也可寫成session.contents(c)=false
⒉Session物件的屬性
CodePage: 可讀/可寫入。整型。定義用於在瀏覽器中顯示頁內容的程式碼頁。代碼頁是字元集的數字值,不同的語言使用
不同的代碼頁。例如,ANSI代碼頁為1252,日文代碼頁為932,簡體中文代碼頁為936。
LCID : 可讀/可寫入。整型。定義傳送給瀏覽器的頁面地區識別。 LCID是唯一地識別地區的一個國際標準縮寫,例如,
2057定義目前地區的貨幣符號是£。
SessionID: 只讀。長整型。傳回本會話的會話標識符。每建立一個會話,由伺服器自動分配一個標識符。可以根據它
的值判斷兩個使用者是誰先訪問伺服器。
Timeout : 可讀/可寫入。整型。為會話定義以分鐘為單位的逾時限定。如果使用者在這個時間內沒有刷新或請求任何一個
網頁,則該使用者產生的會話自動結束。缺省值是20。
以上屬性在實際應用上作用不大,基本上不需要怎麼修改,這幾個屬性也沒什麼特殊的地方。
⒊Session物件的方法
Contents.Remove(變數名稱): 從Session.contents集合中刪除指定的變數
Contents.Removeall() : 刪除Session.contents集合中的所有變數
Abandon() : 結束目前使用者會話並且撤銷目前Session物件。
Session物件的Contents.Remove(變數名稱)和Contents.Removeall()方法與Application物件的基本上沒什麼區別,為
幫助理解,大家可以參考上面的例子將Application改為Session。這裡要說明一下的是Contents.Removeall()和Abandon()
的區別,執行這兩個方法都會釋放當前
使用者會話的所有Session變量,不同的是Contents.Removeall()單純地釋放Session變量的值而不終止當前的會話,而
Abandon()除了釋放Session變數外還會終止會話引發Session_OnEnd事件,希望大家注意兩者的差異。
⒋Session物件的事件
OnStart: 當ASP使用者會話產生時觸發,一旦有任一使用者對本伺服器請求任一頁面即產生此事件。
OnEnd : 當ASP使用者工作階段結束時觸發,使用Abandon()方法或逾時也會觸發該事件。
這兩個事件和Application的OnStart、OnEnd事件一樣,也是必須放在Global.asa檔案裡,下
面就重點和大家研究一下這四個事件的使用。
三、Global.asa
ASP的Application和Session物件體現了其他ASP內建物件所沒有的特徵--事件。每一個訪客訪問伺服器時都會觸發一
個OnStart事件(第一個訪客會同時觸發Application和Session的OnStart事件,但Application先於Session),每位訪客
的會話結束時都會觸發一個OnEnd事件(最後一個訪客會話結束時會同時觸發Application和Session的OnEnd事件,但
Session先於Application)。
OnStart和OnEnd這兩個事件一般應用在虛擬社群中統計線上人數、修改使用者的線上離線狀態等。要具體定義這兩個事
件,需要將程式碼寫在Global.asa文件,並將該文件放在網站的根目錄下(缺省是Inetpubwwwroot)。另外,
Application和Session物件規定了在OnEnd事件裡除了Application物件外其他ASP內建物件(Response、Request、
Server、Session...)一概不能使用。以下舉一個虛擬社群統計線上人數的例子來說明如何使用這兩個事件。
文件說明:
global.asa 位於d:Inetpubwwwroot目錄下
default.asp 位於d:Inetpubwwwroot目錄下,虛擬社群登入頁面
login.asp 位於d:Inetpubwwwroot目錄下,用於偵測使用者輸入的使用者名稱及密碼
index.asp 位於d:Inetpubwwwroot目錄下,虛擬社群首頁
bbs.mdb 位於d:Inetpubwwwroot目錄下,儲存使用者資訊的資料庫
資料庫(ACCESS)結構:
===bbs表===
id 用戶ID,長整型
name 使用者名稱,文字型
code 密碼,文字型
online 在線狀態,是/否
===global.asa===
<script LANGUAGE=VBScript RUNAT=Server>
Sub Application_OnStart
application(online)=0
End Sub
sub Application_OnEnd
nd Sub
Sub Session_OnStart
End Sub
Sub Session_OnEnd
if session.contents(pass) then '判斷是否為登入使用者的Session_OnEnd
application.lock
application(online)=application(online)-1
application.unlock
end if
End Sub
</script>
==============
===login.asp===
……'密碼驗證,連接資料庫,偵測使用者輸入的使用者名稱及密碼是否正確
if 密碼驗證通過then
session(name)=rs(name)
session(id)=rs(id)
session(pass)=true
else
rs.close
conn.close
response.write 密碼錯誤!
response.end
end if
application.lock
application(online)=application(online)+1
conn.Execute (update bbs set online=1 where id=&session(id))'將使用者的狀態設為在線
application.unlock
rs.close
conn.close
response.redirect index.asp '初始化資料後跳到社群首頁
===========
在本例中,用application(online)變數記錄已經登入社群的線上人數,因為一旦有使用者造訪伺服器而不管使用者是否
登錄,都會產生OnStart事件,所以不能在OnStart事件裡使Applicaiton(online)加一。因為不管是否是登入使用者的會話
結束都會產生OnEnd事件(假如有訪客訪問了伺服器但並不登入社區,他的會話結束後也會產生OnEnd事件),所以在
Session_OnEnd事件裡用了句if語句來判斷是否為已登入使用者的OnEnd事件,如果才將線上人數減一。
這只是一個統計線上人數的簡單例子,對於一個完整的虛擬社群來說,僅僅統計有多少人在線上是不夠的,在本例中數
根據庫裡有online欄位是用來記錄使用者的線上狀態,使用者登入的時候,在login.asp裡將online設為1,但用戶離線時並沒
有將online設為0,要完善它,就要修改一下Session_OnEnd事件,在該事件裡將online設為0。
===global. sas===
<script LANGUAGE=VBScript RUNAT=Server>
Sub Application_OnStart
application(online)=0
set application(conn)=Server.CreateObject(ADODB.Connection)
application(db)=Server.MapPath( bs.mdb) '這裡最好使用絕對路徑bs.mdb,下文有詳細介紹
End Sub
sub Application_OnEnd
set application(conn)=nothing
End Sub
Sub Session_OnStart
End Sub
Sub Session_OnEnd
if session.contents(pass) then '判斷是否為登入使用者的Session_OnEnd
application(con).open =driver={Microsoft Access Driver (*.mdb)};dbq=&application(db)
application.lock
application(online)=application(online)-1
application(con).Execute (update friends set online=0 where id=&session.contents(id))
application.unlock
application(con).close
end if
End Sub
</script>
==============
至此,完整的程式碼已經完成了。因為在Application和Session的OnEnd事件裡不能使用Server對象,所以要將資料庫的
連線及資料庫在伺服器上的實體位址(d:inetpubwwwroot bs.mdb)儲存在application變數中,並在
Application_OnStart事件中預先處理。同理,在Session_OnEnd事件中不能用session(pass)來取代session.contents
(pass)(以下有詳盡說明)。
四、本文實例中值得注意的兩點
⒈OnEnd事件裡的session.contents
剛開始接觸global.asa的朋友常常會將上面Session_OnEnd事件裡的
if session.contents(pass) then 寫成
if session(pass) then,
這樣的話系統不會提示錯誤,但永遠也不會執行then後面的內容,這是因為在OnEnd事件裡禁止使用Session對象,
但是可以用Session物件的集合來呼叫session變數。因為IIS並沒有提示任何錯誤訊息,所以筆者曾經在這上面浪費了很多時
間。在此希望大家引以為鑑!
⒉Application_OnStart事件裡用Server.MapPath取得資料庫的實體位址時應使用絕對位址為了說明這個問題,大家可
來做個實驗:將上面Application_OnStart事件裡的
application(db)=Server.MapPath( bs.mdb)改為:
application(db)=Server.MapPath(bbs.mdb)
然後在d:inetpubwwwroot目錄下建立一個test子目錄,寫一個temp.asp在test目錄裡。
====test.asp====
<%response.write application(db)%>
================
再將temp.asp拷貝一份放在根目錄下(d:inetpubwwwroot)。用記事本打開global.asa,再打開兩個瀏覽器,瀏覽器A
輸入網址http://localhost/temp.asp,按下回車,將在瀏覽器上輸出:
d:inetpubwwwroot bs.mdb
然後,在記事本的視窗上點檔案選單,選保存(使global.asa的修改時間改變,從而使IIS重啟動所有服務),再在瀏
覽器B輸入位址http://localhost/test/temp.asp,按回車,瀏覽器上輸出的是:
d:inetpubwwwroot est bs.mdb
global.asa檔案雖然是放在網站根目錄下,但是如果在server.mappath中使用的是相對位址,而觸發Application_OnStart
事件的用戶第一次造訪的頁面又不是屬於根目錄的話,得到資料庫的實體位址將不會是期望的結果,希望大家要特別小心。