我的一亩三分地 我就喜欢!
13fen  设为主页
 收藏本站
 
当前位置: > 一亩三分地:首页 > 网络学院 > 网络编程 > ASP专区 > ASP教程六、使用集合
热门文章排行
热门文章排行 手推车”功能的实现(10-07)
八大法则防范ASP网站漏洞(10-23)
在JSP中访问数据库大全(10-23)
ASP教程十一、调试ASP脚本(10-23)
虚机服务中常见Asp.Net低级错误一览(03-21)
精采文章排行
精采文章排行 ASP.NET实现抓取网页中的链接(11-15)
ASP连接数据库的11种方法(11-10)
如何动态创建网页的RSS内容摘要(11-10)
ASP网站漏洞及入侵防范方法(11-10)
ASP自定义函数:对字符串正则替换(11-10)
技术专题推荐
网管论坛交流
 

ASP教程六、使用集合 

作者:   来源:   点击:   日期:2006-10-23

 

大多数ASP内建对象支持集合。集合是存储字符串、数字、对象和其他值的地方。除了在存储或取出项目时集合会自动扩展与搜索外,集合与数组非常相近。与数组不同的是,集合被修改后,项目的位置将会移动。可以通过集合中项目的名称、索引或者通过在集合的所有项目中遍历访问项目。
  通过名称和索引访问项目
  通过使用项目名称可以访问集合中的具体项目。例如,Contents集合拥有在Session对象中保存的所有变量。同样也拥有由Server.CreateObject创建的所有对象。假设在Session对象中存储了下列用户信息:
<%
Session.Contents(\"FirstName\") = \"Sam\"
Session.Contents(\"LastName\") = \"Woo\"
Session.Contents(\"Age\") = 29
%>
  可以使用在集合中存储项目时关联的名称访问项目。例如,下面的表达式返回字符串“Sam\":
  <%= Session.Contents(\"FirstName\") %>
  通过使用与项目关联的索引或号码也可以访问项目。例如,下面的表达式检索存储在Session对象的第二个存储槽中的信息并且返回\"Woo\":
  <%= Session.Contents(2) %>
  ASP集合从1开始编号。当在集合中增加或删除项目时,与项目关联的索引将会改变。所以不能认为项目的索引始终不变。正如将在下面的主题中说明的那样,利用索引的访问一般用来遍历集合,或访问只读集合中的项目。
  通过使用速记的名称可以访问项目。ASP以特定的顺序搜索与对象关联的集合。如果在对象的集合中特定名称的项目只出现一次的话,可以消除该集合的名称:
  <%= Session(\"FirstName\") %>
  访问存储在Application或Session对象中的项目时,消除集合名称一般是安全的。但是,对于Request对象,最好指定集合名称,因为该集合很可能包含重复的名称。
  遍历集合
  在集合的所有项目中遍历可以了解集合中存储的项目或修改项目。遍历集合时,必须提供集合名称。例如,可以使用VBScript中的For...Each语句访问存储在Session对象中的项目:
<%
\'Declare a counter variable.
Dim Item
\'For each item in the collection, display its value.
For Each Item in Session.Contents
Response.Write Session.Contents(Item) & \"<BR>\"
Next
%>

  可以使用VBScript中的For...Next语句遍历集合。例如,要列出上例中存储在Session中的三个项目,可以使用下列语句。
<%
\'Declare a counter variable.
Dim Item
\'Repeat the loop until the value of counter is equal to 3.
For Item = 1 to 3
Response.Write Session.Contents(Item) & \"<BR>\"
Next
%>
  因为一般不知道存储在集合中的项目个数,ASP支持集合的Count属性,这个属性返回集合中的项目数。可以使Count属性指定计数器的终值。
<%
\'Declare a counter variable.
Dim Item
\'Repeat this loop until the counter equals the number of items
\'in the collection.
For Item = 1 to Session.Contents.Count
Response.Write Session.Contents(Item) & \"<BR>\"
Next
%>
  可以在脚本中使用for语句在集合中循环。在JScript的for语句中使用Count属性时,为了收到更大的效果,应该将Count值分配给本地变量并使用该变量设置计数器终值。这样,脚本引擎就不需要每次循环都查寻Count的值。下面的例子展示了这个技巧:
<%
var item, numitems;
numitems = Session.Contents.Count;
for(item = 1; item <= numitems; item++) {
Response.Write(Session.Contents(item) + \"<BR>\")
}
%>
  Microsoft JScript 3.0引入了Enumerator对象。可以使用该对象遍历ASP集合。atEnd方法指出了集合中是否还存在项目。moveNext方法移动到集合中的下一个项目。
<%
// Create an Enumerator object
var mycoll = new Enumerator(Session.Contents);
//Iterate through the collection and display each item
while (!mycoll.atEnd()) {
var x = mycoll.item();
Response.Write(Session.Contents(x) + \"<BR>\");
mycoll.moveNext();
}
%>
  遍历带子关键字(Subkeys)的集合
  脚本在单一cookie中嵌入相关值以减少在浏览器和Web服务器之间传送的cookie数目。因此Request和Response对象的Cookies集合能够在单一项目中拥有多个值。这些子项目或子关键字可以被单个访问。只有Request.Cookies和 Response.Cookies集合支持子关键字(Subkeys)。Request.Cookies只支持读操作;Response.Cookies只支持写操作。
  可以列举Request.Cookie集合中所有的cookie以及Cookie中所有的子关键字(Subkeys)。但是,如果在没有子关键字(Subkeys)的Cookie上遍历子关键字,将不会产生任何结果。通过使用.HasKeys语法首先检查cookie是否含有子关键字 (Subkeys),就可以避免这种情况。下面的这个例子展示了这
个技巧。
<%
\'Declare counter variables
Dim Cookie, Subkey
\'Display the entire cookie collection.
For Each Cookie in Request.Cookies
Response.Write Cookie & \"<BR>\"
If Request.Cookies(Cookie).HasKeys Then
\'Display the subkeys
For Each Subkey in Request.Cookies(Cookie)
Response.Write Subkey & \"=\" & Request.Cookies(Cookie)(Subkey) & \"<BR>\"
Next
Else
Response.Write \"No subkeys in this cookie <BR>\"
End If
Next
%>

  遍历对象集合
  Session和Application集合可以保存数量变量或者对象实例。Contents集合拥有数量变量和通过调用Server.CreateObject生成的对象实例。StaticObjects集合拥有在Global.asa文件中使用HTML <OBJECT>元素创建的对象。
  在遍历包含对象的集合时,可以访问对象的标识符或对象的方法和属性。例如,假设应用程序使用一些对象创建用户帐号,而且每个对象有初始化方法,可以遍历StaticObjects集合来调用每个初始化方法:
<%
For Each Object in Session.StaticObjects
Session.StaticObjects(Object).InitializeUser
Next
%>
  ASP集合有何不同之处?
  尽管在本主题中讨论的ASP集合与Visual Basic的Collection对象非常相似,但还是有些不同。ASP集合支持Count属性和Item方法,但不支持Add和Remove方法。
  设置对象作用域
  对象的作用域决定哪些脚本可以使用该对象。默认情况下,当您创建对象实例时,该对象具有页作用域。同一ASP页中的任何脚本命令都能使用该页作用域的对象;当ASP页送回客户端时,该对象即被释放。对大多数对象来说,推荐的作用域是页作用域。您可以改变一个对象的作用域,使其可被其他页的脚本使用。本主题将解释如何使用页作用域的对象以及如何改变对象的作用域。
  使用页作用域对象
  在ASP页上用Server.CreateObject创建的对象在该页的生存期内一直存在。该对象对该页的任何脚本命令都是可访问的,当ASP处理完该页时,该对象即被释放。因此,对象具有该页的作用域或生命周期。
  在用Visual Basic或VBScript编程时,要注意在ASP处理完该页之前不要释放对象。例如,以下语句经常用于通过将对象变量赋以Nothing值来释放对象:
  Set myObj = Nothing
  如果您在ASP页中包含了该语句,那么任何使用myObj的企图都将会返回一个预期的错误代码。但在内部,即使在对象释放以后,ASP仍保留对它的引用。当您在脚本中不能使用对象时,对象的资源直到ASP处理完页之后才释放。同样,如果您通过创建另一个对象实例并将其赋给已使用过的对象变量来释
放该对象时,ASP 将保留对原对象实例的引用。对大多数脚本来说,创建多个对象可能不会产生问题,但如果对象使用共享资源,比如数据库连接,就有可能出现问题。
  由于对象有页作用域,所以不要依靠手工释放的对象。例如,以下的循环创建1001个Connection对象,它将能打开大多数的连接甚至于一个大型的SQL server:
<%
For I = 0 to 1000
Set Conn = Server.CreateObject(\"ADODB.Connection\")
Conn.Open \"connection string\"
Next
%>
  总的来说,应该尽量避免在一个循环内部创建对象。如果无法避免,您应该手工释放被对象使用过的资源。如果Connection对象仅被创建一次,且数据资源的物理连接在每个循环中被打开然后关闭,那么上例将会正常运行:
<%
Set Conn = Server.CreateObject(\"ADODB.Connection\")
For I = 0 to 1000
Conn.Open \"connection string\"
Conn.Close
Next
%>
  为对象赋予会话作用域
  在应用程序中,对于每个新会话,都会创建session-scope对象,并且在会话结束后会将其释放。因此,每个活动的会话都有一个对象。会话作用域用于从多个脚本中调用的对象,但只影响一个用户会话。您可以只在需要时才为对象赋予会话作用域。如果确实需要使用会话作用域,那么就必须了解提供对象的组件的线程模型,因为它影响性能和对象的安全环境。详细信息,请参阅本主题的“高级信息:性能问题” 。
  要为对象赋予会话作用域,请将对象存储在ASPSession内建对象中,您既可以在Global.asa文件中使用<OBJECT>标记,也可以在ASP页上使用Server.CreateObject方法创建具有会话作用域的对象实例。
  在Global.asa文件中,您可用扩展了RUNAT属性(必须设置为Sever)和SCOPE属性(必须设置为Session)的<OBJECT> 标记。以下示例创建一个Ad Rotator对象的会话作用域实例:

<OBJECT RUNAT=Server SCOPE=SessionID=MyAd PROGID=\"MSWC.Adrotator\">
</OBJECT>
  一旦您在Session对象中存储了对象,您就可以从应用程序的任何页中访问该对象。下面的语句使用上例中由<OBJECT> 标记创建的对象实例:
  <%= MyAd.GetAdvertisement(\"addata.txt\") %>
  在ASP页上,您也可以使用Server.CreateObject方法将对象存储在Session内建对象中。以下示例在Session对象中存储Ad Rotator对象的一个实例。
<% Set Session(\"MyAd\") = Server.CreateObject(\"MSWC.Adrotator\") %>
  要显示广告,您首先应该获取存储在Session对象中的Ad Rotator对象的实例,然后才能调用方法来显示对象:
<% Set MyAd = Session(\"MyAd\") %>
<%= MyAd.GetAdvertisement(\"addata.txt\") %>
  在用<OBJECT>标记声明的对象被某个.asp文件中的脚本命令引用之前,ASP并不创建其实例。Server.CreateObject方法则立即创建该对象实例。
  因此,对会话作用域对象来说,使用<OBJECT>标记要比Server.CreateObject属性更好。
  为对象赋予应用程序作用域
  application-scope对象是在应用程序启动时就创建的对象的单个实例。该对象由所有客户端请求共享。仅在极少数情况下,您才需要为对象赋予应用程序作用域。一些实用程序对象,例如计数器等,可能需要应用程序作用域。但一般来说,您可用在下一节中建议的替代方案。另外,线程模型会影响性能和对象安全环境(请参阅本主题的“高级信息:性能问题”)。
  要为对象赋予应用程序作用域并将其存储在ASPApplication内建对象中,既可以使用Global.asa文件中的<OBJECT>标记,也可以使用ASP页上的Server.CreateObject方法创建应用程序作用域的对象实例。
  在Global.asa文件中,您可用扩展了RUNAT属性(必须设置为Sever)和SCOPE属性(必须设置为Session)的<OBJECT> 标记。在ASP页中,您可以使用Server.CreateObject将对象实例存储在Application内建对象中。关于使用<OBJECT>标记和Server.CreateObject的示例,请参阅上一节"为对象赋予会话作用域"。
  会话和应用程序作用域的替代方案
  仅当需要时,才能为对象赋予会话或应用程序作用域。因为在会话或应用程序结束运行之前,这些对象会一直保留。它们会占用内存或数据库连接等资源,这些资源可能会在其他方面更有用。另外,组件的线程模型会影响您从中所创建的对象的性能,尤其是那些具有会话或应用程序作用域的对象。
  在很多情况下,比创建应用程序或会话作用域对象更好的方法就是利用会话或应用程序作用域变量,将信息传递给在网页一级创建的对象。例如,不要为ADO Connection对象赋予会话或应用程序作用域,因为它创建的连接会在相当长的一段时间一直保持打开而此时脚本已不再使用ODBC连接共享。但您可以将ODBC连接字符串存储在Session或 Application内建对象中,并在网页上从创建的Connection对象实例中获取该字符串。通过这种方式,您可以存储在会话或应用程序名称空间中频繁使用的信息,但只有在需要时才创建用该信息的对象。关于作用域变量的详细信息,请参阅“使用变量和常量”。
  用户自定义的JScript对象
  您可以通过定义一个创建和初始化新对象的属性和方法的构造函数来创建自己的JScript对象。当脚本用new操作符来调用构造函数时,就会创建该对象的实例。ASP脚本支持用户自定义的对象,当具有页作用域时,后者正常运行。但如果为用户自定义的JScript对象赋予应用程序或会话作用域,将可
能影响该对象的功能。特别是,若一个对象具有会话或应用程序作用域,则其他页的脚本可以获取该对象的属性,但是却不能调用其方法。
  高级信息:性能问题
  组件的线程模型可能会影响Web站点的性能,一般来说,带有Both标记的对象是推荐在所有的ASP脚本中使用的对象,尤其是在Session和Application对象中。不推荐使用单线程对象,因为您可能不会始终控制所用对象的线程模型,所以,以下的指导可帮助您获得最佳性能:
页作用域对象。带有Both或Apartment标记的对象将给予您最佳的性能。
应用程序作用域对象。一般来说,应避免在Application对象中放置对象。如果确需使用应用程序作用域对象,您会从结合了FreeThreadedMarshaler的带有Both标记的对象中获得最佳性能。您既可以用<OBJECT>标记也可以用Server.CreateObject方法在Application 对象中存储带有Single、Free或Both标记的对象。您必须用单元线程对象来使用<OBJECT>标记。
会话作用域对象。带有Both标记的对象将为您提供最佳性能。用单线程或单元线程对象会导致Web服务器将会话锁定在一个线程上。自由线程对象不会锁定会话,但运行速度不高。在Session对象中,您可以用 <OBJECT>标记或Server.CreateObject方法存储对象。
  如果您已安装了SDK文档,请参阅"创建ASP组件”,您将会获得有关线程模型及其隐含的组件性能的详细信息。(在Windows 95及其后续版本中SDK文档不可用。)

 

 



文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【论坛讨论

   相关文章:
·ASP教程五、使用变量和常量 ·ASP教程七、ASP内置对象
·ASP教程四、使用脚本语言 ·ASP教程八、向浏览器发送内容
·ASP教程三、创建ASP页 ·ASP教程九、包含文件

   文章评论:(条)
  
 请留名: 匿名评论   点击查看所有评论 网管论坛
 

  责任编辑:一分  声明:刊登此文章是为了传递更多信息,文章内容仅供参考,转载请注明出处。