Pergunta

O ASP clássico tem um recurso que é o equivalente de PHP de "incluem uma vez" recurso?

Foi útil?

Solução

Eu sei que este é um tema antigo, mas eu pensei que eu gostaria de acrescentar meus dois centavos no caso de qualquer pessoa interessada.

Eu escrevi uma função que faz exatamente o que você quer:. Inclui o arquivo dado exatamente um, não importa quantas vezes ele foi chamado

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

Notas:

  • Este usa uma função simulado do falso com uma propriedade padrão. Se Incomoda você, é facilmente reformulado.
  • O dicionário deve ser persistente através de todos inclui, enquanto persistindo o FSO meramente evita reconstruindo-o. Se você não gosta da idéia de mantê-los em torno depois das importações são feitas, você pode modificar a classe para obter sintaxe como esta:

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

Outras dicas

No. Desculpe. Você tem que gerir inclui-se.

Esta foi uma das que concorreu pela primeira vez da questão para depois de herdar um ASP aplicativo legado. Minha solução atualmente é incluir todos os arquivos de biblioteca genric em um arquivo chamado 'app-init.asp'. Este arquivo é então incluído em todas as páginas e dar é você um único ponto de entrada para ligar aplicativo ampla funcionalidade e uma base para construir em.

Graças Thom Smith para o seu pedaço de código.

A seguir uma versão com base em seu para arquivos de origem alça UTF8 (e que administra abertura e fechamento marcas 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

Como você pode ver, eu não fechar o fluxo para deixar ainda inclui a ser processado.

Update: Desde caminhos são maiúsculas e minúsculas, esta versão converte-los para minúsculas antes de adicionar ao dicionário como chaves. Além disso eles são adicionados antes avaliação código, para duplicar previne avaliações em caso de circuito de inclusão (recursão):

Dada A.asp e B.asp:

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

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

Desde A ainda não é avaliada em tudo na inclusão de código B, o segundo IncludeOnce ocorrerá uma avaliação duplicado se ainda não está registrado no dicionário, que não vai querer. Esta atualização corrige o problema.

O melhor que você pode fazer é usar SSI para incluir arquivos:

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

Como uma advertência para a resposta usando ExecuteGlobal; Eu acho que ExecuteGlobal cria instabilidade como VBScript não faz coleta de lixo ou gerenciar a memória também. Pode jogar "falha catastrófica" ou "ASP 0240 Script Engine Exception" erros porque você está redefinindo um objeto que não foi correctamente eliminados.

Assim, para usar isso, você também precisa fazer o seu inclui, Classes que têm destruidores e incluem deve criar uma instância da classe, persistem o nome do objeto no dicionário e o destruidor ImportFunction deve destruir todos os objetos na dicionário.

Inclui não deve ser prefixado com ASP tag <%%> quer, enquanto usando um #include, você precisa.

Você também deve observar que ExecuteGlobal, considera tudo X = Y a ser atribuição e não comparação, assim: -

IsMatch = (X = Y) 'pode produzir resultados falsos.

Exemplo incluem: -

Class aClass

    Public Sub doSomething()
        ...
    End Sub

End Class

Dim instance
Set instance = new aClass

Eu criei um exemplo similar ao anterior, mas usando o segundo estilo de passar a incluir a um Sub ou propriedade atribuição

O que também faz, é tentativas de coleta de lixo, destruindo todos os objetos no dicionário, em sua própria destruição. Ele também retira as tags ASP para as bibliotecas que você embrulhadas.

<% 
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
%>

Uso: -

With RequireOnce 
    .Include "aClass",        "instance"
    .Include "Database",      "DataAccess"
    .Include "Constants",     "Constant"
    .Include "LoginCheck",    "Login"
End With
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top