1. 程式人生 > >寫COM元件用於ASP/PHP等動態網頁

寫COM元件用於ASP/PHP等動態網頁

   ASP、PHP等動態網頁語言的功能已很強大,但COM能使它如虎添翼。其實我們平時用的ADO、FSO、Jmail等也就是COM。藉助COM,WEB可以呼叫本地應用程式的幾乎所有功能來反饋給頁面。例如,查詢伺服器的各盤使用情況,CPU佔用率等,最後給出一個例子,用COM查詢IP對應的地埋位置。

   開發COM的工具也就是開發EXE應用程式的工具,VB、VC、Delphi都可以。但VB具有天生的優勢,幾行程式碼就可以寫出COM來。VB中,COM又叫ActiveX DLL。下面借用一個很簡單的示例 ,判斷年份是否為閏年。

   新建一個ActiveX DLL工程,將工程名命為CheckYear,自動生成的類名命為LeapYear。寫下如下程式碼:

Option Explicit
Public Function IsLeapYear(yr As Variant) As Boolean
    If yr Mod 4 = 0 And yr Mod 100 <> 0 Then IsLeapYear = True Else IsLeapYear = False
End Function

  咳,簡單得有點不適應。就這樣COM做好了,生成DLL即可。然後註冊它。在執行中輸入“regsvr32 H:\checkyear.dll”即可。如果你本機架有IIS或NetBox,可以在ASP網頁上呼叫它了。如果用於伺服器,那麼上面這件事則需要在伺服器上做。ASP呼叫程式碼如下:
<% Option Explicit
Dim oCheckYear,s
Dim Year, isleapYear
Year=2004
Set oCheckYear=CreateObject("CheckYear.LeapYear")
isleapyear=oCheckYear.IsLeapYear(Year)
Set oCheckYear=Nothing
%>
<body>
<% If isleapYear=True Then s="是閏年!" Else s="不是閏年!"
%>
<%=Year%>年<%=s%>
</body>
  COM在EXE應用開發工具中也可以呼叫。在寫複雜的COM時,可以用他們來檢測功能。COM註冊後,在VB中的“引用”列表中可以看到。例如下面是VB呼叫它的程式碼:
Private Sub Command1_Click()
    Dim c
    Set c = CreateObject("CheckYear.LeapYear")
    Dim d As Boolean
    d = c.IsLeapYear(2004)
    MsgBox d
End Sub


  COM打開了一扇無限可能的門,下面就是看你發揮了。金蝶、用友等非常擅用此類方法。它們主要是把COM當成標準DLL用(因為VB開發標準DLL不方便啊),利用工作分配豚團隊合作。下面給出一個用COM查詢IP對應的地埋位置的例子。WebService想必大家用過,很多門戶或廠商以免費的WebService的方式提供天氣、股市等資訊。我們在程式中直接用URL就可以訪問它。這裡要說的是一個非公開的、非正式的“服務”,即IP138網站提供的IP資訊查詢頁面,http://iframe.ip138.com/ic.asp,它返回簡單的IP和所在地資訊,如“您的IP是:[17.89.9.11] 來自:廣東省深圳市 電信”。我的程式中就向它請求資訊查詢使用者所在地,這比自己查資料庫省事多了,而且它號稱它的地址永遠是最新的。可是好景不長,這個URL穩定地存在了N年,卻在最近失效了。不過,我們很快可以找到其他頁面。這個也可以用到COM中,之後,我們自己的頁面上只要呼叫COM中提供的方法就可以了。有人要問:這樣豈不總是得到伺服器的地址資訊?事實上,IP138同時也提供對指定IP的查詢

。查詢IP的網站非常多,百度一下有幾百個,如http://ip.cn/index.php?ip=211.11.85.5,新浪的http://int.dpool.sina.com.cn/iplookup/iplookup.php?ip=22.73.22.80等,URLk末尾ip=x.x.x.x即是指查詢該IP的地理位置。要注意字符集問題,如果是GBKakGB2312的則中文無需特別處理,如果是utf-8或其他,則需轉換一下,否則會出現亂碼。

    VB中新建ActiveX DLL工程,名為IP2City,建個類名為clsIP,方法名GetCityName,輸入引數是IP字串,輸出為城市名(地理位置)。程式碼如下:

Option Explicit
Public Function GetCityName(vIP As Variant) As String
    Dim sUrl As String, sCode As String, sCity As String, c() As String, d() As String
    sUrl = "http://ip138.com/ips138.asp?ip=" & vIP 
    sCode = GetURL(sUrl)
    c = Split(sCode, "本站主資料:")
    If UBound(c) >= 1 Then
        sCity = c(1)
        d = Split(sCity, "</li>")

        sCity = d(0)
        
    End If

    If Len(sCity) > 20 Then sCity = Left(sCity, 20)
    GetCityName = sCity
End Function
Public Function GetURL(URL) As String
    On Error GoTo a0:
    Dim i, j
    j = 0
    Dim XMLHTTP As Object
    Set XMLHTTP = CreateObject("MSXML2.XMLHTTP")
    If Not IsObject(XMLHTTP) Then
        Set XMLHTTP = CreateObject("Microsoft.XMLHTTP")
        If Not IsObject(XMLHTTP) Then Exit Function
    End If
    XMLHTTP.Open "GET", URL, True
    XMLHTTP.setRequestHeader "If-Modified-Since", "0"    '使用MSXML2.XMLHTTP和Microsoft.XMLHTTP方法時,這條指令相當於清除快取
    XMLHTTP.send
    i = Now()
    Do    'While XMLHTTP.ReadyState <> 4
        DoEvents
    Loop Until XMLHTTP.ReadyState = 4 Or j = DateDiff("s", i, Now()) > 4
    GetURL = StrConv(XMLHTTP.responseBody, vbUnicode)
    Exit Function
a0:
End Function

    編譯後,這個COM既可以用於EXE應用程式,也可以用於ASP/PHP等動態頁面。例如下面是ASP中呼叫的程式碼:
<% 
'Option Explicit  
Dim oIP,sFrom,sCityName  
sFrom=request.ServerVariables("REMOTE_ADDR") 
Set oIP=CreateObject("IP2City.clsIP")
sCityName=oIP.GetCityName(sFrom)  
Set oIP=Nothing  
%>  
<body>  
<center>您的IP是:[<%=sFrom%>] 來自:<%=sCityName%>  
</body>  

  最後提一下COM註冊問題。我的開發機器是Win7 64位,開發、註冊到呼叫都很順利,然而拷到伺服器Win2003上之後ASP卻無法呼叫。顯示“沒有許可權 'Create Object'”錯誤。熱百度上幾乎千篇一律只有一個答案,在控制面板中如何如何,而對自制控制元件不適用。折騰了幾個小時,最終的解決方法是,在DLL檔案的屬性-安全頁中,手工增加使用者EveryOne。這麼所謂增加安全性?我只能說:微軟大腦有屎,浪費別人時間就是浪費別人生命。

    全文結束。