  | 
				VFP 愛用者社區 本討論區為 Visual Foxpro 愛用者經驗交流的地方, 請多多利用"搜尋"的功能, 先查看看有無前例可循, 如果還有不懂的再發問. 部份主題有附加檔案, 須先註冊成為社區居民才可以下載.   
				 | 
			 
		 
		 
	
		| 上一篇主題 :: 下一篇主題   | 
	 
	
	
		| 發表人 | 
		內容 | 
	 
	
		goto-dream
 
 
  註冊時間: 2004-05-11 文章: 909
 
  第 1 樓
  | 
		
			
				 發表於: 星期六 九月 25, 2004 2:03 am    文章主題: Visual Foxpro與ASP應用(轉貼) | 
				     | 
			 
			
				
  | 
			 
			
				Visual Foxpro與ASP相結合開發Web數據庫應用 
 
 
    1、VFP與Web數據庫應用 ----作為最成功的大眾數據庫,Foxpro簡便易學,有廣大的用戶。隨著VFP 5.0的推出,VFP已經成為一個強大的企業級開發工具。它不僅可以開發文件/服務器(F/S)數據庫應用,也可以開發C/S應用,這時VFP作為一個前端工具,後端可以SQL Server,Sybase等數據庫Engine。通過Remote View和SQL Passthrough函數,VFP可以像操作本地數據一樣,方便地處理服務器端數據。 
 
---- 在Internet/ntranet影響日益巨大的今天,開 Web數據庫應用成為引人關注的技術。Web數據庫應用有一個天然的多層C/S結構。在這個結構中,客戶端(Client)僅由Browser組成,幾乎沒有軟件維護和升級的問題。來自Client的請求發送到Web Server,我們只須開發Web Server端軟件,處理請求,與數據庫服務器交互、並把結果返回Client,系統維護和升級非常方便。只 要允許,任意一個客戶都可以通過Internet或Intranet訪問我們的數據。 
 
 
----VFP完全具備開發Web數據庫應用的能力。不過有意思的是,這次VFP被推到了後台,在數據庫服務器上專門處理數據存取和實現 商業邏輯。數據庫服務器和Web Server可以運行在同一個網絡服務器上,或者運行在由高速通道連接的兩台網絡服務器上(如NT Server),這樣網絡傳輸瓶頸不再存在。並且借助NT Server的安全管理,客戶並不能直接接觸VFP數據庫,而是通過Web Server存取數據,VFP數據庫的安全特性得以大大提高,而此兩項一般認為是VFP的重要弱點。 
 
 
    2、ASPActive Server Page)與 VFP的組件技術----Web數據庫應用可以由CGI、ISAPI、IDC、ASP等實現。其中ASP的功能最為強大,在其中可以混用HTML、DHTML、ActiveX、VBSsript 或JavaSript,特別是可以使用服務器端組件。此服務器端組件可以用VFP、VB、VC++、Delphi等任意支持COM技術的語言編寫,以實現用戶特定的商業邏輯。如果不出意外,ASP將成為主流技術。目前有Microsoft的IIS(Internet Information Server,NT Server)和PWS(Personel Web Server,Win95)支持ASP。
 
 
----在傳統的F/S或C/S應用中,組件作為面向對象的編程風格,你可以隨自己的喜好,採用或不採用它。然而在ASP中使用VFP,組件(一個OLE Server DLL)是你唯一的選擇。你的處理過程都應封裝在一個或多個組件中。 
 
 
    3、使用的環境和工具----對於ASP ,需要WinNT 4.0(Service Pack 3)、IIS 3.0(WinNT自帶)、Visual InterDev1.0 。也可以是:Win95、PWS(Visual InterDev1.0中提供) 、Visual InterDev1.0。
 
 
----為了使IIS或PWS支持ASP,在安裝Visual InterDev時必須首先在服務器上選擇安裝其中的Server Components:FrontPage Server Extensions和Active Server Pages,然後在開發服務器上安裝Client Components:Visual InterDev Client。也可以把這些都安裝在同一台機器上,這樣可以在單機上方便地編程、調試。 
 
 
    4、VFP組件的實現----在VFP中開始一個Project,取名為Classes,然後在此Project中建立一個Program,取名Classdef.prg。它定義了一個OneRecord類,其功能是一條條顯示一個數據庫,具有向前、向後和定位能力。使用一個DBF文件d:\vfpweb\data\booksno.dbf,結構為: 
 
Field_name Field_type Field_len
 
bookno C 16
 
bookname C 50
 
author C 12
 
editor C 14
 
pubdate D 8
 
charnum N 4.0 
 
 
在Classdef.prg中鍵入代碼:
 
Define class onerecord as custom olepublic
 
mcDatapath=""
 
*---------------------------
 
function getdatapath
 
return (this.mcdatapath)
 
*---------------------------
 
function getcurrentno
 
return recno()
 
*---------------------------
 
function init
 
set exclu off
 
set century on
 
set date to ansi
 
return
 
*---------------------------
 
function setdatapath
 
lparameter cpath
 
if type("cpath")< >"C" 
 
return 
 
endif
 
this.mcdatapath=cpath
 
set defau to (cpath)
 
if not used("booksno")
 
select 0
 
use booksno
 
else
 
select booksno
 
endif 
 
return
 
*--------------------------
 
function movenext
 
if .not.eof() 
 
skip
 
endif
 
return 
 
*--------------------------
 
function moveprevious
 
if .not.bof() 
 
skip -1
 
endif
 
return
 
*--------------------------
 
function destroy
 
use
 
*clear all &&clear all將掛起服務器
 
return
 
*--------------------------
 
function iseof
 
if eof() 
 
return .t.
 
else
 
return .f.
 
endif
 
*--------------------------
 
function isbof
 
if bof() 
 
return .t.
 
else
 
return .f.
 
endif
 
*--------------------------
 
function getbookno
 
return bookno
 
*--------------------------
 
function getpubdate
 
if empty(pubdate)
 
return ""
 
else
 
return pubdate
 
endif
 
*--------------------------
 
function geteditor
 
return editor
 
*--------------------------
 
function getbookname
 
return bookname
 
*--------------------------
 
function goto
 
lparameter recnum
 
if type("recnum")< >"N" &&error data type
 
 
return
 
endif
 
if recnum< 1 .or. recnum >reccount()
 
return
 
else
 
goto (recnum)
 
endif
 
return
 
EndDefine
 
----在菜單Project,選中Set Main,然後Build ,在Build對話框中選Build OLE DLL。好了,我們到此就完成了一個OLE Server,並且它已經自動註冊在我們的機器上。我們可以在菜單Project|Project Info彈出的Project Information對話框中看到這個組件的信息: 
 
 
Server Classes:onerecord
 
Project Name:Classes
 
OLE
 
----Server的引用方法是createobject("ProjectName.ClassName"),對於我們這個組件,就是:createobject("classes.onerecord")。可以直接在VFP的Command窗口中交互式地測試之,在Command窗口中鍵入: 
 
 
ox=createobject("classes.onerecord")
 
ox.setdatapath("d:\vfpweb\data")
 
?ox.bookname
 
?ox.getbookname
 
ox.movenext
 
?ox.getbookname
 
ox.goto(30)
 
?ox.getbookname
 
----可以直接看到執行結果,最後不要忘了釋放該組件: 
 
release ox
 
----這個組件是針對特定數據庫進行操作的,測試很方便。下面,我們再實現一個更為一般的類ClsQ2T,其功能是任意指定一條SQL查詢語句(針對任意一個或多個數據庫),將查詢結果以表格的形式顯示在Web頁面上,其中使用了ASP的接口。它不僅封裝了數據 處理,而且通過ASP接口,也封裝了數據顯示。 
 
 
---- 仍在Classdef.prg之中,接著最後一行代碼,鍵入: 
 
 
***************************************************
 
define class clsq2t as custom olepublic
 
mcontext=.null.
 
*-----------------------------------------
 
function onstartpage(ocontext)
 
this.mcontext=ocontext &&對ASP接口的引用
 
return
 
*-----------------------------------------
 
function init 
 
set exclu off
 
set safety off
 
return
 
*---------------------------------------------
 
function setdatapath(strpath)
 
merrnum=0
 
on error merrnum=error( )
 
set default to (strpath)
 
if merrnum< >0 
 
return "Error in setdatapath"+message()+chr(13)
 
endif
 
on error
 
return "OK,setdatapath"+strpath+chr(13)
 
*-------------------------------------------------
 
*函數querytotable要求傳入一個SQL Select串,如:
 
* "select bookname,editor from booksno where charnum >500"
 
* -------------------------------------------------
 
function querytotable(querystring)
 
merrnum=0
 
on error merrnum=error( )
 
oResp=this.mcontext.response &&引用ASP對像response
 
tempname=SUBSTR(SYS(2015), 3, 10) &&產生唯一的文件名
 
&querystring into cursor (tempname)
 
if merrnum< >0 
 
return "Error in querytotable,create sql view"+message()
 
+alltrim(str(lineno( )))+chr(13)
 
endif
 
outstring="< table border=1 >"+chr(13)+"< tr >"+chr(13)
 
oresp.write(outstring)
 
if merrnum< >0 
 
return "Error in querytotable,oresp.write"+message()
 
+alltrim(str(lineno( )))+chr(13)
 
endif
 
outstring=""
 
fc=fcount()
 
for i=1 to fc
 
if type("eval(field(i))")="G" 
 
loop
 
endif
 
outstring=outstring+"< td >"+field(i)+"< /td >"+chr(13)
 
next
 
outstring=outstring+"< /tr >"+chr(13)
 
oresp.write(outstring)
 
outstring=""
 
if merrnum< >0 
 
return "error in oresp.write header"+message()
 
+alltrim(str(lineno( )))+chr(13)
 
endif
 
scan
 
outstring=outstring+"< tr >"+chr(13)
 
for i=1 to fc 
 
if type("eval(field(i))")="G" 
 
loop
 
endif
 
mt=eval(field(i))
 
do case
 
case type("mt")="C"
 
outstring=outstring+"< td >"+mt+"< /td >"
 
case type("mt")="T"
 
outstring=outstring+"< td >"+ttoc(mt)+"< /td >"
 
case type("mt")="D"
 
outstring=outstring+"< td >"+dtoc(mt)+"< /td >" 
 
case type("mt")$"NY"
 
outstring=outstring+"< td >"+alltrim(str(mt,5))+"< /td >"
 
endcase
 
outstrin=outstring+chr(13)
 
next 
 
outstring=outstring+"< /tr >"+chr(13)
 
endscan
 
oresp.write(outstring)
 
outstring="< /table >"
 
oresp.write(outstring)
 
use
 
on error
 
return "OK of querytotable, ended"+chr(13)
 
endfunc
 
EndDefine
 
----鍵入代碼後Build,在Build對話框中仍選Build OLE DLL,在確認覆蓋時選擇"Y",在Project Information對話框中看到這個組件的信息已有變化: 
 
 
Server Classes:onerecord clsq2t 
 
Project Name:Classes
 
---- 加上了新增的clsq2t。 
 
 
----這段代碼中較特別的是onstartpage(ocontext),它在每次.asp頁面啟動時由IIS自動調用,並傳入一個參數。該參數是對ASP的一個容器ScriptingContext的引用,通過它可以引用ASP的所有內在對像(Intrinsic Object),如response、reuqest。通過這些內在對象,VFP可以直接讀取用戶在Web頁面上的輸入,也可以把結果直接寫回Web頁面。 
 
 
----組件clsq2t的調試要困難得多。可以在函數querytotable中註釋掉與oResp有關的行以及define class clsq2t as custom olepublic和EndDefine兩行,然後增加一些代碼直接調用各個函數,以進行調試排錯。確認無誤後再恢復上述各行,並重新Build。 
 
 
    5、在ASP中使用VFP組件----下面將建立兩個ASP頁面:Onerecord.asp和Clsq2t.asp測試我們完成的這兩個組件。啟動Visual InterDev,開始一個新的工程:New Projects,然後選取Web Project Wizard ,在Project Name中輸入VFPClasses,點擊OK後,Visual InterDev產生一些輔助文件,為新的工程做好準備,然後打開該工程。我們在該工程中首先建立一個HTML頁面index.htm,以調用上述兩個ASP頁面。點擊菜單File|New,在New對話框中選Files|HTML Page,並指定HTML頁面的名字:index.htm。Visual InterDev將會為我們產生一個空的框架,在其中用手工加入代碼,也可用Visual InterDev附帶的FrontPage Editor等可視化工具編輯代碼,完成後的HTML頁面如下: 
 
< HTML >
 
< HEAD >
 
< /HEAD >
 
< BODY >
 
< p >< a href="Onerecord.asp" >To scan the records< /a >
 
< /p >
 
< p >To send a query:< br >
 
< form action="Clsq2t.asp" method="post" name="input" >
 
< input type="submit" name="Btoquery" value="Query" >
 
< input type="text" size="40" name="qstring" 
 
value="Input a query here" > 
 
< /p >
 
< /form >
 
< /BODY >
 
< /HTML >
 
----index.htm中包括一個到Onerecord.asp的超聯接、一個Text用於輸入查詢語句、一個Submit Button用於提交查詢,點擊該Button後將調用Clsq2t.asp。 
 
 
----點擊菜單File|New,在New對話框中選Files|Active Server Page,新建Onerecord.asp,它使用onerecord組件在Web頁面上瀏覽數據庫,代碼如下: 
 
 
< %@ LANGUAGE="VBSCRIPT" % >
 
< html >
 
< HEAD >
 
< /HEAD >
 
< BODY >
 
< FORM ACTION="Onerecord.asp" METHOD="POST" ID="scanform" >
 
< %set ox=server.createobject("classes.onerecord")
 
ox.setdatapath("d:\vfpweb\data")
 
if session("currentno")="" then
 
session("currentno")=1'first time open the page
 
currentno=1
 
else
 
if isnumeric(session("currentno")) then
 
currentno=session("currentno")
 
else
 
currentno=1
 
end if
 
end if
 
ox.goto(currentno)
 
% >
 
< %if request.form("cmdnext")< >"" then
 
ox.movenext
 
end if% >
 
< %if request.form("cmdprev")< >"" then
 
ox.moveprevious
 
end if% >
 
< %if isnumeric(request.form("txtgoto")) then
 
temp=cint(request.form("txtgoto"))
 
ox.goto(temp)
 
end if% >
 
< %session("currentno")=ox.getcurrentno% >
 
< p >
 
當前記錄:< %=ox.getcurrentno% >< br >
 
書 號:< %=ox.getbookno% >< br >
 
書 名:< %=ox.getbookname% >< br >
 
責 編:< %=ox.geteditor% >< br >
 
出版時間:< %=ox.getpubdate% >< br >
 
< /p >
 
< p >
 
< %if not ox.iseof then'如果不是文件未則顯示按鈕Next% >
 
< INPUT TYPE=submit VALUE="Next" NAME="cmdnext" >
 
< %end if% > 
 
< %if not ox.isbof then'如果不是文件頭則顯示按鈕Prev% >
 
< INPUT TYPE=submit VALUE="Prev" NAME="cmdprev" >
 
< %end if% >
 
< %set ox=nothing% >
 
< INPUT LANGUAGE="VBScript" TYPE=submit 
 
VALUE="Goto" 
 
ONCLICK="if not isnumeric(scanform.txtgoto.value) then
 
window.alert("Must input a number")
 
window.event.cancelbubble=true
 
end if"
 
NAME="cmdgoto" >
 
< INPUT TYPE=text SIZE=20 NAME="txtgoto" >< /p >
 
< a href=index.htm > Return Index< /a >
 
< /FORM >
 
< /BODY >
 
< /HTML >
 
----該頁面顯示數據庫當前記錄各字段的值,並在頁面下方顯示三個按鈕Next(下一條),Prev(上一條)和Goto。其中使用了Server Side Code(符號< % 和% >之間的代碼,在服務器端執行),產生組件及對組件各方法和屬性的調用;Client Side Code(在客戶端執行),在ONCLICK的事件響應中檢驗用戶輸入的記錄號(必須是一個數字)。由於Web Browser基於的HTTP是一個無狀態協議,它並不知道各客戶的當前記錄。為了在各個頁面調用中記住當前記錄號,使用了session對象。session對像在跟蹤和保持客戶的使用狀態上很有用處,感興趣者可以查閱Visual InterDev的聯機幫助。 
 
 
----再新建Clsq2t.asp,它使用使用clsq2t組件在Web頁面上顯示任意查尋結果,代碼如下: 
 
 
< %@ LANGUAGE="VBSCRIPT" % >
 
< HTML >
 
< HEAD >
 
< /HEAD >
 
< BODY >
 
< %qs=request.form("qstring")% >
 
你輸入的查詢要求是: < br >< %=qs% >< hr >
 
< a href=index.htm > Return Index< /a >< br >
 
< %set ox=Server.CreateObject("classes.clsq2t")% >
 
< %ox.SetDataPath("d:\vfpweb\data")% >
 
< %ox.QueryToTable(qs)% >
 
< %Set ox = Nothing% >
 
< /BODY >
 
< /HTML >
 
----由於輸出操作都已封裝在組件clsq2t之中,故該組件的使用相當簡明。應該指出的是,該組件應該用於開發之中,而不應提供給最終用戶,因為不能保證用戶輸入的SQL Select串的有效和合法。 
 
 
    6、調試注意事項----此處兩個組件皆是進程內服務器,當有Bug時將會使系統掛起甚至崩潰。 
 
----當修改組件代碼時,你會發現無法覆蓋老的.dll文件。這是因為即使退出Visual InterDev,組件仍被Web Server鎖定(這就 是為什麼VFP試圖用clear all釋放資源時會掛起服務器)。這時必須停止Web Server並再啟動之,在開發過程中可能要如此反覆多次。如果系統被掛起或崩潰,Web Server無法響應,這時只有使出最後一招:關機並重新啟動。VFP 5.0版本的Run Time Library只支持一個實例,就是說:如果上述兩個組件在兩個不同的prg文件中實現,則它們不能同時被使用。這一點在VFP6.0中已得到改進(但仍是單線程的)。 
 
 
    7、評述----Web數據庫開發更專業化的方法似乎是ASP+VB+ADO(ActiveX Data Object)+SQLServer。其中ADO不僅可用於Web數據庫開發,也可用在VB、VFP中替代DAO、RDO開發傳統的C/S應用,功能更為強大。然而對於中小企業來說,VFP簡便易用,對資源要求不高,而且我國很多高校學生都學習過Foxbase 或Foxpro,他們可以很快掌握Visual Foxpro,故可以比較容易地找到編程和系統維護人才。VFP用於開發Internet/Intranet是一個較好的選擇,國外已有許多大型應用的成功凡例。 _________________ 福隆昌淨水有限公司--淨水器的專家,淨水器,飲水機,濾心!!
 
 
想了解更多,您可上幸福雞湯組.找尋!!丁澐瑄.老師.
 
 
          愛作夢 | 
			 
		  | 
	 
	
		| 回頂端 | 
		 | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
  	 
	    
  	   | 
 	
您 無法 在這個版面發表文章 您 無法 在這個版面回覆文章 您 無法 在這個版面編輯文章 您 無法 在這個版面刪除文章 您 無法 在這個版面進行投票 您 無法 在這個版面附加檔案 您 無法 在這個版面下載檔案
  | 
   
  
		 |