문제

ASP Classic에는 PHP의 "포함 된 한 번"기능과 동등한 기능이 있습니까?

도움이 되었습니까?

해결책

나는 이것이 오래된 주제라는 것을 알고 있지만 누군가가 관심을 가질 경우 2 센트를 추가 할 것이라고 생각했습니다.

나는 당신이 원하는 것을 정확하게하는 함수를 썼습니다. 주어진 파일을 몇 번이나 호출하든 정확히 하나를 포함합니다.

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
    

다른 팁

아뇨. 죄송합니다. 당신은 자신을 포함해야합니다.

이것은 레거시 ASP 앱을 물려받은 후 처음으로 실행 한 문제 중 하나였습니다. 내 솔루션은 현재 'app-init.asp'라는 파일에 모든 유전자 라이브러리 파일을 포함합니다. 그런 다음이 파일은 모든 페이지에 포함되어 있으며 앱 넓은 기능을 연결하기위한 단일 입력 지점과 빌드 할 기반을 제공합니다.

당신의 코드에 대한 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 사전에 아직 등록되지 않은 경우 중복 평가가 발생합니다. 이 업데이트는 문제를 해결합니다.

당신이 할 수있는 최선은 SSI를 사용하여 파일을 포함하는 것입니다.

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

ExecuteGlobal을 사용하여 답변에 대한 경고로; vbscript가 쓰레기를 수집하거나 관리하지 않기 때문에 ExecuteGlobal은 불안정성을 생성한다고 생각합니다. 올바르게 폐기되지 않은 개체를 재정의하기 때문에 "치명적인 실패"또는 "ASP 0240 스크립트 엔진 예외"오류를 던질 수 있습니다.

따라서이를 사용하려면 소멸자가 포함 된 클래스를 포함시켜야하며 포함은 클래스의 인스턴스를 생성하고 사전에서 객체 이름을 지속 시키며 ImportFunction Destructor는 사전의 모든 객체를 파괴해야합니다.

포함은 ASP 태그 < % %>로 접두사를 접두사하지 않아야하지만 #include를 사용하면 필요합니다.

또한 executeGlobal은 모든 x = y를 할당으로 간주하고 비교가 아니라는 점에 유의해야합니다.

ismatch = (x = y) '는 가짜 결과를 일으킬 수 있습니다.

예제는 다음과 같습니다.

Class aClass

    Public Sub doSomething()
        ...
    End Sub

End Class

Dim instance
Set instance = new aClass

위의 것과 유사한 예제를 만들었지 만 포함을 서브 또는 속성 할당에 전달하는 두 번째 스타일을 사용했습니다.

그것이하는 일은, 사전의 모든 물체를 자체 소멸자로 파괴하여 쓰레기 수집을 시도하는 것입니다. 또한 포장 한 라이브러리의 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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top