Asp Clássico Incluir Uma vez
-
03-07-2019 - |
Pergunta
O ASP clássico tem um recurso que é o equivalente de PHP de "incluem uma vez" recurso?
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,"<","<") & "</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
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:
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