Asp Classic包含一次

时间:2009-05-01 21:42:19

标签: asp-classic include

ASP Classic的功能是否相当于PHP的“包含一次”功能?

7 个答案:

答案 0 :(得分:13)

我知道这是一个古老的话题,但我想我会加上我的两分钱,以防任何人有兴趣。

我编写了一个能够完全按照你想要的方式运行的函数:无论调用它多少次,都包含给定的文件。

class ImportFunction
    private libraries_
    private fso_

    private sub CLASS_INITIALIZE
        set libraries_ = Server.createObject("Scripting.Dictionary")
        set fso_ = Server.createObject("Scripting.FileSystemObject")
    end sub

    public default property get func (path)
        if not libraries_.exists(path) then

            on error resume next
            with fso_.openTextFile(path)
                executeGlobal .readAll
                if Err.number <> 0 then 
                    Response.write "Error importing library "
                    Response.write path & "<br>"
                    Response.write Err.source & ": " & Err.description
                end if
            end with
            on error goto 0

            libraries_.add path, null
        end if
    end property
end class
dim import: set import = new ImportFunction

注意:

  • 这使用了使用默认属性模拟的虚函数。如果这困扰你,那很容易重构。
  • 字典必须通过所有包含持久化,而持久化fso只是避免重构它。如果您不喜欢在导入完成后保留它们的想法,您可以修改类以获得如下语法:

    with new Importer
        .import "foo"
        .import "bar/baz"
    end with
    

答案 1 :(得分:4)

没有。抱歉。你必须管理包括你自己。

答案 2 :(得分:2)

这是我继承遗留ASP应用程序后首次遇到的问题之一。我的解决方案目前是将所有genric库文件包含在名为“app-init.asp”的文件中。然后,此文件将包含在所有页面中,并为您提供一个单一的入口点,以连接应用程序范围的功能和构建的基础。

答案 3 :(得分:2)

感谢Thom Smith提供的代码。

在基于您的版本下面处理UTF8源文件(以及管理打开和关闭ASP标记的人)。

Dim IncludeOnce
Class IncludeOnceClass

    Private libraries_
    Private adostream_

    Private Sub CLASS_INITIALIZE
        Set libraries_ = Server.createObject("Scripting.Dictionary")
        Set adostream_ = CreateObject("ADODB.Stream")
        adostream_.CharSet = "utf-8"
        adostream_.Open
    End Sub

    Public Default Property Get includeFile (path)
        Dim lpath : lpath=LCase(path)
        if Not libraries_.exists(lpath) then
            Dim code
            libraries_.add LCase(lpath), "stuff"
            On Error Resume Next
            adostream_.LoadFromFile(lpath)
            code = Replace(Replace(adostream_.ReadText(),"<"&"%",""),"%"&">","")
            executeGlobal code
            If Err.number <> 0 Then 
                Response.write "Error importing library "
                Response.write lpath & "<br>"
                Response.write Err.source & ": " & Err.description
                Response.write "<pre><tt>" & replace(code,"<","&lt;") & "</tt></pre>"
                Response.End
            End if
            On Error Goto 0
        End If
    End Property

End Class

Set IncludeOnce = new IncludeOnceClass

如您所见,我不会关闭该流,以便进一步处理。

更新:由于路径不区分大小写,因此在将词典添加为键之前,此版本会将它们转换为小写。此外,在代码评估之前添加了,以防止在包含循环(递归)的情况下重复评估:

鉴于A.asp和B.asp:

' A.asp
IncludeOnce Server.MapPath("/some/path/B.asp")

' B.asp
IncludeOnce Server.MapPath("/some/path/A.asp")

由于在A代码包含时尚未评估B,如果第二个IncludeOnce尚未在字典中注册,则第二个{{1}}将发生重复评估,我们不想要。此更新解决了此问题。

答案 4 :(得分:1)

您可以做的最好的事情是使用SSI来包含文件:

http://en.wikipedia.org/wiki/Server_Side_Includes

答案 5 :(得分:1)

使用ExecuteGlobal作为答案的警告;我认为ExecuteGlobal会产生不稳定性,因为VBScript不会很好地收集或管理内存。它可能会导致“灾难性故障”或“ASP 0240脚本引擎异常”错误,因为您正在重新定义未正确处理的对象。

因此,要使用它,您还需要使您的包含,具有析构函数的类和包含应该创建类的实例,在字典中保留对象名称,并且ImportFunction析构函数应该销毁所有对象。字典。

包含不应以ASP标记为前缀&lt; %%&gt;或者,使用#include,你需要。

你还应该注意到ExecuteGlobal认为所有X = Y都是赋值而不是比较,所以: -

isMatch =(X = Y)'可能会产生虚假结果。

示例包括: -

Class aClass

    Public Sub doSomething()
        ...
    End Sub

End Class

Dim instance
Set instance = new aClass

我创建了一个与上面类似的示例,但使用第二种方式将include传递给Sub或属性赋值

它还做了什么,是通过销毁字典中的所有对象(在它自己的析构函数中)来进行垃圾收集。它还剥离了你包装的库的asp标签。

<% 
Class Libraries

private m_LoadedLibraries
private m_FileSystem

Private Property Get LoadedLibraries
    If Not isInstantiated( m_LoadedLibraries ) Then
        Set m_LoadedLibraries = Server.CreateObject("Scripting.Dictionary")
    End If
    Set LoadedLibraries = m_LoadedLibraries
End Property

Private Property Get FileSystem
    If Not isInstantiated( m_FileSystem ) Then
        Set m_FileSystem = Server.CreateObject("Scripting.FileSystemObject")
    End If
    Set FileSystem = m_FileSystem
End Property

Private Property Get IncludePath
    IncludePath = "c:\include\"
End Property

Private Property Get LibrarySuffix
    LibrarySuffix = ".inc.asp"
End Property

Private Sub Class_Terminate()

    destroyObjects

    Set m_LoadedLibraries   = Nothing
    Set m_FileSystem        = Nothing

End Sub

Private Sub destroyObjects()
    Dim objectName
    For Each objectName in LoadedLibraries.Items
        If Eval("IsObject(" & objectName & ")") Then
            Execute "Set " & objectName & " = Nothing"
        End If
    Next
End Sub

Public Sub Include(ByVal libraryName, ByVal objectName)

    libraryName = LCase( libraryName )
    Dim library, filePath, script

    If Not LoadedLibraries.Exists( libraryName ) Then
        filePath = IncludePath + libraryName + LibrarySuffix 
        Set library = FileSystem.OpenTextFile( filePath  )
        script = library.ReadAll
        script = stripAspTags( script )
        ExecuteGlobal script
        library.Close
        LoadedLibraries.add libraryName, objectName
    End If

End Sub

Private Function stripAspTags(ByVal script)
    Dim buffer, location, startTag, stopTag, tagLength 

    startTag    = Chr(60) + "%"
    stopTag     = "%" + Chr(62)
    script      = CStr( script )
    tagLength   = Len(startTag)
    location = InStr(1, script, startTag, 1 )

    If location > 0 Then
        buffer = cleanString( Left( script, location + tagLength - 1  ) )
         ' Only strip off if it's the first part of the script
        If Len( buffer ) = Len(startTag) Then
            script = Mid( script, location + tagLength )
        End If
    End If

    location = InStrRev(script, stopTag, -1, 1 )
    If location > 0 Then
        buffer = cleanString( Mid( script, location ) )
         ' Only strip off if it's the last part of the script
        If Len( buffer ) = Len(stopTag) Then
            script = Left( script, location - 1 )
        End If
    End If
    stripAspTags = script
End Function

Private Function cleanString(ByVal target)
    Dim objRegExp

    Set objRegExp           = New Regexp

    objRegExp.IgnoreCase    = True
    objRegExp.Global        = True
    objRegExp.Pattern       = "[\x00-\x1f]+"
    cleanString             = objRegExp.Replace( target, "")

    Set objRegExp = Nothing
End Function

Private Function isInstantiated(ByVal target)
    isInstantiated = ( IsNull( target) Or IsEmpty( target ) Or Not IsObject( target) )
End Function    


End Class

Dim RequireOnce
Set RequireOnce = new Libraries
%>

用法: -

With RequireOnce 
    .Include "aClass",        "instance"
    .Include "Database",      "DataAccess"
    .Include "Constants",     "Constant"
    .Include "LoginCheck",    "Login"
End With

答案 6 :(得分:0)

这是将文件包含到Asp Classic中的方法。

包含此文件,它看起来会灰显,但包含文件。