找回密码
 注册

QQ登录

只需一步,快速开始

查看: 7379|回复: 14

[asp] 分享一个好东东,动态Include文件 (Dynamic File Includes)

[复制链接]
发表于 2008-4-8 16:16:39 | 显示全部楼层 |阅读模式
相信很多ASP开发者都会抱怨ASP的Include方式太老土了,以的方式加载文件实在是太不舒服了,在实际项目中不管我是不是一开始就要用到这个文件,我总得早早的把它Include进来...这方面PHP就舒服很多...什么时候用,什么时候In...

早在03年就在蓝色理想上看到过动态Include的文章,当时已经觉得很厉害,但实际应用了一下,不方便而且Include的效果不好.

后来又在一网站上看到了改进版的,但是也不太好用~~~

哎,当时我真是觉得有点想放弃ASP了,但是由于公司还是用ASP来开发,我也是没有办法...

今天,我一定要记住今天~~~在国外的一个网站上我竟然发现了这样一个好东东,太棒了~~~Great works!!!

以前试的一些动态Include代码,都无法Include一个类,甚至函数~~~又或者Include文件中的Include无法被包含...

现在这个鬼佬(dselkirk)写的类可以为我们做到这些了~~~


  1. <%
  2.   public include, include_vars
  3.   set include = new cls_include

  4.   class cls_include

  5.     private sub class_initialize()
  6.       set include_vars = server.createobject("scripting.dictionary")
  7.     end sub
  8.     private sub class_deactivate()
  9.       arr_variables.removeall
  10.       set include_vars = nothing
  11.       set include = nothing
  12.     end sub

  13.     public default function include(byval str_path)
  14.       dim str_source
  15.       if str_path <> "" then
  16.         str_source = readfile(str_path)
  17.         if str_source <> "" then
  18.           processincludes str_source
  19.           convert2code str_source
  20.           formatcode str_source
  21.           if str_source <> "" then
  22.             if request.querystring("debug") = 1 then
  23.               response.write str_source
  24.               response.end
  25.             else
  26.               executeglobal str_source
  27.               include_vars.removeall
  28.             end if
  29.           end if
  30.         end if
  31.       end if
  32.     end function

  33.     private sub convert2code(str_source)
  34.       dim i, str_temp, arr_temp, int_len
  35.       if str_source <> "" then
  36.         if instr(str_source,"%" & ">") > instr(str_source,"<" & "%") then
  37.           str_temp = replace(str_source,"<" & "%","|%")
  38.           str_temp = replace(str_temp,"%" & ">","|")
  39.           if left(str_temp,1) = "|" then str_temp = right(str_temp,len(str_temp) - 1)
  40.           if right(str_temp,1) = "|" then str_temp = left(str_temp,len(str_temp) - 1)
  41.           arr_temp = split(str_temp,"|")
  42.           int_len = ubound(arr_temp)
  43.           if (int_len + 1) > 0 then
  44.             for i = 0 to int_len
  45.               str_temp = trim(arr_temp(i))
  46.               str_temp = replace(str_temp,vbcrlf & vbcrlf,vbcrlf)
  47.               if left(str_temp,2) = vbcrlf then str_temp = right(str_temp,len(str_temp) - 2)
  48.               if right(str_temp,2) = vbcrlf then str_temp = left(str_temp,len(str_temp) - 2)
  49.               if left(str_temp,1) = "%" then
  50.                 str_temp = right(str_temp,len(str_temp) - 1)
  51.                 if left(str_temp,1) = "=" then
  52.                   str_temp = right(str_temp,len(str_temp) - 1)
  53.                   str_temp = "response.write " & str_temp
  54.                 end if
  55.               else
  56.                 if str_temp <> "" then
  57.                   include_vars.add i, str_temp
  58.                   str_temp = "response.write include_vars.item(" & i & ")"  
  59.                 end if
  60.               end if
  61.               str_temp = replace(str_temp,chr(34) & chr(34) & " & ","")
  62.               str_temp = replace(str_temp," & " & chr(34) & chr(34),"")
  63.               if right(str_temp,2) <> vbcrlf then str_temp = str_temp
  64.               arr_temp(i) = str_temp
  65.             next
  66.             str_source = join(arr_temp,vbcrlf)
  67.           end if
  68.         else
  69.           if str_source <> "" then
  70.             include_vars.add "var", str_source
  71.             str_source = "response.write include_vars.item(""var"")"
  72.           end if
  73.         end if
  74.       end if
  75.     end sub

  76.     private sub processincludes(str_source)
  77.       dim int_start, str_path, str_mid, str_temp
  78.       str_source = replace(str_source,"<!-- #","<!--#")
  79.       int_start = instr(str_source,"<!--#include")
  80.       str_mid = lcase(getbetween(str_source,"<!--#include","-->"))
  81.       do until int_start = 0
  82.         str_mid = lcase(getbetween(str_source,"<!--","-->"))
  83.         int_start = instr(str_mid,"#include")
  84.         if int_start >  0 then
  85.           str_temp = lcase(getbetween(str_mid,chr(34),chr(34)))
  86.           str_temp = trim(str_temp)
  87.           str_path = readfile(str_temp)
  88.           str_source = replace(str_source,"<!--" & str_mid & "-->",str_path & vbcrlf)
  89.         end if
  90.         int_start = instr(str_source,"#include")
  91.       loop
  92.     end sub

  93.     private sub formatcode(str_code)
  94.       dim i, arr_temp, int_len
  95.       str_code = replace(str_code,vbcrlf & vbcrlf,vbcrlf)
  96.       if left(str_code,2) = vbcrlf then str_code = right(str_code,len(str_code) - 2)
  97.       str_code = trim(str_code)
  98.       if instr(str_code,vbcrlf) > 0 then
  99.         arr_temp = split(str_code,vbcrlf)
  100.         for i = 0 to ubound(arr_temp)
  101.           arr_temp(i) = ltrim(arr_temp(i))
  102.           if arr_temp(i) <> "" then arr_temp(i) = arr_temp(i) & vbcrlf
  103.         next
  104.         str_code = join(arr_temp,"")
  105.         arr_temp = vbnull
  106.       end if
  107.     end sub

  108.     private function readfile(str_path)
  109.       dim objfso, objfile
  110.       if str_path <> "" then
  111.         if instr(str_path,":") = 0 then str_path = server.mappath(str_path)
  112.         set objfso = server.createobject("scripting.filesystemobject")
  113.         if objfso.fileexists(str_path) then
  114.           set objfile = objfso.opentextfile(str_path, 1, false)
  115.           if err.number = 0 then
  116.             readfile = objfile.readall
  117.             objfile.close
  118.           end if
  119.           set objfile = nothing
  120.         end if
  121.         set objfso = nothing
  122.       end if
  123.     end function

  124.     private function getbetween(strdata, strstart, strend)
  125.       dim lngstart, lngend
  126.       lngstart = instr(strdata, strstart) + len(strstart)
  127.       if (lngstart <> 0) then
  128.         lngend = instr(lngstart, strdata, strend)
  129.         if (lngend <> 0) then
  130.           getbetween = mid(strdata, lngstart, lngend - lngstart)
  131.         end if
  132.       end if
  133.     end function

  134.   end class
  135. %>
复制代码
发表于 2008-4-8 17:12:10 | 显示全部楼层
不太懂耶。
回复 支持 反对

使用道具 举报

发表于 2008-4-8 19:36:31 | 显示全部楼层
不错,不过用的时候貌似要把 processincludes 函数里的 #include 给拆开,要不会出错
回复 支持 反对

使用道具 举报

发表于 2008-4-8 19:52:34 | 显示全部楼层
ExecuteGlobal 语句
要求
版本 1

执行一个功多个在脚本全局名字空间中指定的语句。

  1. ExecuteGlobal statement
复制代码

statement 参数是一个包含一个或多个可执行语句的字符串表达式。在statement 参数中可以包含多条语句, 使用冒号将其分开。

说明
在 VBScript 中, x = y 有两种解释方法。第一种方法是作为一条赋值语句, 将 y 的值赋给 x。第二种方法是作为一个表达式,用于测试 x 和 y 是否具有相同的值。如果它们相等,则结果为 True; 如果他们不相等,其结果为 False.ExecuteGlobal 语句总是使用第一种方法,而 Eval 方法总是使用第二种方法。

注意   在 Microsoft&reg; JScript™ 中, 赋值与比较之间不存在混消,因为赋值运算符(=) 不同于比较运算符。
在脚本的全局名字空间中,ExecuteGlobal 中的所有语句都有是可执行的。因此,允许您将代码添加到程序中,以便于任何过程能够对其进行访问。例如,一个 VBScript Class 语句在运行时可以执行。随之函数创造此类的一个新实例。

在运行时添加过程和类是非常有用的,但是也可能导致在运行时覆盖已有的全局变量和函数。因为这可能导致非常严重的程序问题,因此,当使用 ExecuteGlobal 语句时一定得非常谨慎。如果您无需访问过程之外的变量或函数,最好使用Execute 语句,因为它只影响主调函数的名字空间。

下面的例子解释了 ExecuteGlobal 语句的用法。

  1. Dim X         ' 声明 X 为全局变量。
  2. X = "Global"      ' 给全局变量 X 赋值。
  3. Sub Proc1   ' 声明过程。
  4.   Dim X      ' 在局部变量中声明 X。
  5.   X = "Local"   ' 给局部变量 X 赋值。
  6.          ' 此处的可执行语句
  7.          ' 创建一个过程, 当被调用时, 打印 X。
  8.          ' 此处将打印全局变量 X 的值,因为 Proc2
  9.          ' 继承了全局变量中的一切。
  10.   ExecuteGlobal "Sub Proc2: 打印 X: End Sub"
  11.   Print Eval("X")   ' 打印局部 X。
  12.   Proc2      ' 在全局作用区域中调用 Proc2
  13.              ' 将打印 "Global" 。
  14. End Sub
  15. Proc2        ' 此行将导致错误
  16.              ' 因为 Proc2 在 Proc1 之外是不可用的。
  17. Proc1         ' 调用 Proc1。
  18.   Execute "Sub Proc2: 打印 X: End Sub"
  19. Proc2         ' 此行调用成功,因为 Proc2
  20.          ' 在全局作用区域中是可用的。
复制代码
下面的例子演示了 ExecuteGlobal 语句可以被重写,因此您无需将下面的整个过程都包括在引用标记之内。

  1. S = "Sub Proc2" & vbCrLf
  2. S = S & "  Print X" & vbCrLf
  3. S = S & "End Sub"
  4. ExecuteGlobal S
复制代码


摘自《Microsoft Windows 脚本技术》
回复 支持 反对

使用道具 举报

发表于 2008-4-9 01:25:05 | 显示全部楼层
说说几点局限:
1.被包含文件中不能有"Option Explicit"语句;
2.被包含文件中不能有<%@LANGUAGE="VBSCRIPT" CODEPAGE="936"%>类似语句
3.被包含文件中不能轻易出现"|",例如Response.Wirte("mzwu|com")将导致出错
4.<!-- #include file="file2.asp" -->这边的file2.asp必须使用双引号,否则file2.asp将包含不进来

针对上边提出的3,4点两个问题,目前对类代码做了些修改,修改后如下:

  1. <%
  2. public include, include_vars
  3. set include = new cls_include

  4. class cls_include

  5.         private sub class_initialize()
  6.                 set include_vars = server.createobject("scripting.dictionary")
  7.         end sub

  8.         private sub class_deactivate()
  9.                 arr_variables.removeall
  10.                 set include_vars = nothing
  11.                 set include = nothing
  12.         end sub

  13.         public default function include(byval str_path)
  14.                 dim str_source
  15.                 if str_path <> "" then
  16.                         str_source = readfile(str_path)
  17.                         if str_source <> "" then
  18.                                 processincludes str_source
  19.                                 convert2code str_source
  20.                                 formatcode str_source
  21.                                 if str_source <> "" then
  22.                                         if request.querystring("debug") = 1 then
  23.                                                 response.write str_source
  24.                                                 response.end
  25.                                         else
  26.                                                 executeglobal str_source
  27.                                                 include_vars.removeall
  28.                                         end if
  29.                                 end if
  30.                         end if
  31.                 end if
  32.         end function

  33.         private sub convert2code(str_source)
  34.                 dim i, str_temp, arr_temp, int_len
  35.                 dim str_separator
  36.                 str_separator = "$|"
  37.                 if str_source <> "" then
  38.                         if instr(str_source,"%" & ">") > instr(str_source,"<" & "%") then
  39.                                 str_temp = replace(str_source,"<" & "%",str_separator & "%")
  40.                                 str_temp = replace(str_temp,"%" & ">",str_separator)
  41.                                 if left(str_temp,1) = str_separator then str_temp = right(str_temp,len(str_temp) - len(str_separator))
  42.                                 if right(str_temp,1) = str_separator then str_temp = left(str_temp,len(str_temp) - len(str_separator))
  43.                                 arr_temp = split(str_temp,str_separator)
  44.                                 int_len = ubound(arr_temp)
  45.                                 if (int_len + 1) > 0 then
  46.                                         for i = 0 to int_len
  47.                                                 str_temp = trim(arr_temp(i))
  48.                                                 str_temp = replace(str_temp,vbcrlf & vbcrlf,vbcrlf)
  49.                                                 if left(str_temp,2) = vbcrlf then str_temp = right(str_temp,len(str_temp) - 2)
  50.                                                 if right(str_temp,2) = vbcrlf then str_temp = left(str_temp,len(str_temp) - 2)
  51.                                                 if left(str_temp,1) = "%" then
  52.                                                         str_temp = right(str_temp,len(str_temp) - 1)
  53.                                                         if left(str_temp,1) = "=" then
  54.                                                                 str_temp = right(str_temp,len(str_temp) - 1)
  55.                                                                 str_temp = "response.write " & str_temp
  56.                                                         end if
  57.                                                 else
  58.                                                         if str_temp <> "" then
  59.                                                                 include_vars.add i, str_temp
  60.                                                                 str_temp = "response.write include_vars.item(" & i & ")"
  61.                                                         end if
  62.                                                 end if
  63.                                                 str_temp = replace(str_temp,chr(34) & chr(34) & " & ","")
  64.                                                 str_temp = replace(str_temp," & " & chr(34) & chr(34),"")
  65.                                                 if right(str_temp,2) <> vbcrlf then str_temp = str_temp
  66.                                                 arr_temp(i) = str_temp
  67.                                         next
  68.                                         str_source = join(arr_temp,vbcrlf)
  69.                                 end if
  70.                         else
  71.                                 if str_source <> "" then
  72.                                         include_vars.add "var", str_source
  73.                                         str_source = "response.write include_vars.item(""var"")"
  74.                                 end if
  75.                         end if
  76.                 end if
  77.         end sub

  78.         private sub processincludes(str_source)
  79.                 dim int_start, str_path, str_mid, str_temp
  80.                 str_source = replace(str_source,"<!-- #","<!--#")
  81.                 int_start = instr(str_source,"<!--#include")
  82.                 str_mid = lcase(getbetween(str_source,"<!--#include","-->"))
  83.                 do until int_start = 0
  84.                         str_mid = lcase(getbetween(str_source,"<!--","-->"))
  85.                         int_start = instr(str_mid,"#include")
  86.                         if int_start >  0 then
  87.                                 if instr(str_mid,chr(34))=0 then
  88.                                         str_temp = replace(replace(str_mid,"#include",""),"file=","")
  89.                                 else
  90.                                         str_temp = lcase(getbetween(str_mid,chr(34),chr(34)))
  91.                                 end if
  92.                                 str_temp = trim(str_temp)
  93.                                 str_path = readfile(str_temp)
  94.                                 str_source = replace(str_source,"<!--" & str_mid & "-->",str_path & vbcrlf)
  95.                         end if
  96.                         int_start = instr(str_source,"#include")
  97.                 loop
  98.         end sub

  99.         private sub formatcode(str_code)
  100.                 dim i, arr_temp, int_len
  101.                 str_code = replace(str_code,vbcrlf & vbcrlf,vbcrlf)
  102.                 if left(str_code,2) = vbcrlf then str_code = right(str_code,len(str_code) - 2)
  103.                 str_code = trim(str_code)
  104.                 if instr(str_code,vbcrlf) > 0 then
  105.                         arr_temp = split(str_code,vbcrlf)
  106.                         for i = 0 to ubound(arr_temp)
  107.                                 arr_temp(i) = ltrim(arr_temp(i))
  108.                                 if arr_temp(i) <> "" then arr_temp(i) = arr_temp(i) & vbcrlf
  109.                         next
  110.                         str_code = join(arr_temp,"")
  111.                         arr_temp = vbnull
  112.                 end if
  113.         end sub

  114.         private function readfile(str_path)
  115.                 dim objfso, objfile
  116.                 if str_path <> "" then
  117.                         if instr(str_path,":") = 0 then str_path = server.mappath(str_path)
  118.                         set objfso = server.createobject("scripting.filesystemobject")
  119.                         if objfso.fileexists(str_path) then
  120.                                 set objfile = objfso.opentextfile(str_path, 1, false)
  121.                                 if err.number = 0 then
  122.                                         readfile = objfile.readall
  123.                                         objfile.close
  124.                                 end if
  125.                                 set objfile = nothing
  126.                         end if
  127.                         set objfso = nothing
  128.                 end if
  129.         end function

  130.         private function getbetween(strdata, strstart, strend)
  131.                 dim lngstart, lngend
  132.                 lngstart = instr(strdata, strstart) + len(strstart)
  133.                 if (lngstart <> 0) then
  134.                         lngend = instr(lngstart, strdata, strend)
  135.                         if (lngend <> 0) then
  136.                                 getbetween = mid(strdata, lngstart, lngend - lngstart)
  137.                         end if
  138.                 end if
  139.         end function
  140.        
  141. end class
  142. %>
复制代码


修改说明:convert2code函数中增加了一个变量str_separator,可自由定义分隔符,降低出错率。

讨论交流:http://www.mzwu.com/article.asp?id=1475

[[i] 本帖最后由 dnawo 于 2008-4-9 02:31 编辑 ]
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-4-9 13:23:57 | 显示全部楼层
测试一下dnawo修改先~~~
回复 支持 反对

使用道具 举报

发表于 2008-4-9 14:45:13 | 显示全部楼层
  1. Function include(filename)
  2.         Dim re,content,fso_include,f,aspStart,aspEnd
  3.        
  4.         set fso_include=CreateObject("Scripting.FileSystemObject")
  5.         set f=fso_include.OpenTextFile(server.mappath(filename))
  6.                 content=f.ReadAll
  7.                 f.close
  8.         set f=nothing
  9.         set fso_include=nothing
  10.        
  11.         set re=new RegExp
  12.                 re.pattern="^\s*="
  13.                 aspEnd=1
  14.                 aspStart=inStr(aspEnd,content,"<%")+2
  15.                
  16.                 do while aspStart>aspEnd+1
  17.                         Response.write Mid(content,aspEnd,aspStart-aspEnd-2)
  18.                         aspEnd=inStr(aspStart,content,"%\>")+2
  19.                         Execute(re.replace(Mid(content,aspStart,aspEnd-aspStart-2),"Response.Write "))
  20.                         aspStart=inStr(aspEnd,content,"<%")+2
  21.                 loop
  22.                
  23.                 Response.write Mid(content,aspEnd)
  24.                
  25.         set re=nothing
  26.        
  27.        
  28. End Function
复制代码
回复 支持 反对

使用道具 举报

发表于 2008-4-9 22:25:14 | 显示全部楼层
楼上的不支持多重include
包含文件中的函数似乎不能被调用
回复 支持 反对

使用道具 举报

发表于 2008-4-10 09:07:25 | 显示全部楼层
不是很明白谁来详细讲讲
回复 支持 反对

使用道具 举报

发表于 2008-4-17 10:59:34 | 显示全部楼层
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-4-18 13:56:30 | 显示全部楼层
这个看了,很不错~~~
回复 支持 反对

使用道具 举报

发表于 2008-4-18 14:52:18 | 显示全部楼层
这个我以前也写过一个,当时发了没人理
http://bbs.blueidea.com/thread-2733357-1-1.html

后来又发了这个
http://bbs.blueidea.com/thread-2733022-1-1.html

[[i] 本帖最后由 cjj 于 2008-4-18 15:00 编辑 ]
回复 支持 反对

使用道具 举报

发表于 2008-4-28 04:39:19 | 显示全部楼层
原帖由 [i]ljlyy 于 2008-4-17 10:59 发表
看看这个asp框架
http://code.google.com/p/kissaspframework/



大概看了一下,这套程序,我觉得只能称之为功能类的封装
与我想像中的框架,有很大一部分距离啊
看看thinkphp的思路,也许你会认为这个ASP做得并不够好
国内很多CMS都已经做到了像他这样的

不过,里面还是有很多地方是值得借鉴的

谢谢推荐
回复 支持 反对

使用道具 举报

发表于 2008-4-28 11:07:07 | 显示全部楼层
如果有注释就好了
回复 支持 反对

使用道具 举报

发表于 2008-9-9 17:56:27 | 显示全部楼层
include 新的文件会出错. 造成打不开页面.
重复调用时,会提示convert2code里的集合已经存在.
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|Archiver|手机版|blueidea.com ( 湘ICP备19000417号-2 )

GMT+8, 2021-9-26 04:51 , Processed in 0.065092 second(s), 9 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表