本文讨论了从PHP(PHP:HypertextPreprocessor4)到ASP.NET的迁移,并对PHP和Microsoft®VisualBasic®.NET的基本语法以及基本功能和体系结构进行了对比。
尽管使用PHP和ASP.NET都可以构建复杂的Web应用程序(例如电子商务站点、Intranet和企业门户),但两者之间却存在若干重要差别。与PHP不同,ASP.NET并不是一种语言或分析器,而是Microsoft.NETFramework中的一组用于构建Web应用程序和XMLWebService的技术。同PHP一样,MicrosoftASP.NET页面在服务器上执行并生成标记(例如HTML、WML或XML),标记将发送给桌面应用程序或移动应用程序。但不同的是,ASP.NET为开发Web页面提供了强大的、面向对象的以及由事件驱动的编程模型,同时仍保留了PHP开发人员所习惯的那种简单性。
ASP.NET应用程序是基于强大的面向对象编程(OOP)模式,而不是基于脚本模式。这样便可以获得更为严谨的OOP功能,例如继承、封装和反射。虽然大多数基本的简单操作可以轻松地从PHP转换到ASP.NET,但要转换更为复杂的应用程序却并不这么简单,这需要仔细的规划和考虑,并采用更符合OOP的方法。
本文假设读者具有PHP方面的经验,并且对编程和软件开发有着基本了解。本文首先从代码方面对两者的基础体系结构的差别进行简单比较,并简要介绍一下OOP开发模型,然后比较两者的功能,最后将使用PHP和ASP.NET开发Web应用程序时的语法和常见任务作以对比。
注意:如果您希望跳过有关迁移的详细信息,而只想尝试ASP.NET的使用,则可以直接跳到建议的后续操作部分。 体系结构对比阅读完本文后,通过比较语法和语言,您将了解PHP和ASP.NET是很相似的,它们具有类似的功能和语法。但是,从更基本的体系结构层面来讲,PHP与ASP.NET却有着很大差别。PHP基于独立于平台的处理器/引擎,该处理器/引擎用于分析PHP脚本、提供数据库连接、符合Internet协议以及提供大多数Web应用程序平台所常见的众多其他任务。
ASP.NET是基于一系列技术(如CLR)构建的框架,提供了大量以很好的方式组织的类库,这些类库可满足要在Web应用程序中使用的大多数功能的需要。您还可以轻松地创建各种组件,对该框架进行扩展。
虽然PHP也提供了类似的功能(例如PEAR库),但PHP和ASP.NET并非完全相同,因为ASP.NET框架是完全基于OOP模式和OOP概念构建的,而PHP则不然。这种差别在PHP和ASP.NET中类和对象的访问方式方面表现得犹为明显。
PHP和ASP.NET中的面向对象编程虽然PHP和ASP.NET都为应用程序开发提供了OOP模式,但它们对各种OOP概念(例如封装和多态)的支持却存在差别。例如,PHP仅支持部分封装(例如,支持在类中声明方法和字段)和部分多态(没有重载和抽象)。此外,由于PHP的类中不存在私有(private)、公有(public)或受保护(protected)函数等概念以及重载,因此PHP也不支持这些概念及其访问。OOP纯粹主义者可能会说,ASP.NET以及各种语言也没有完全支持OOP模式中的所有概念,对于使用OOP的大多数语言(如C++和Java)来说,情况确实如此。
这既有积极的一面,也有消极的一面。消极的一面是:对于某些Web开发人员来说,学习ASP.NET要比学习PHP困难些,因为PHP提供的是开发人员创建Web站点时所惯用的脚本模式。但是,使用过OOP语言和/或V的开发人员会发现ASP.NET比较亲切且易于学习。
ASP.NET支持OOP概念的积极的一面是,ASP.NET应用程序的大多数部分都会得到很好的设计,并且能够对内容、逻辑和数据进行清楚的分隔,因而从应用程序生命周期的长远角度看,这通常更容易为其提供支持。此外,由于ASP.NET本身支持企业技术,例如消息队列、事务(请参阅.NETFramework的System.EnterpriseServices类)SNMP和Web服务,因而可以很容易地开发具有高度可缩放性的强大的应用程序。
要大致了解面向对象编程(从VisualBasic的角度)的主要概念,请参阅功能PHPASP.NET编码语言具有旧ASP样式标记的C、C++样式脚本语言。支持某些OOP概念。支持超过25种语言,但最常用的两种语言是VisualBasic.NET和C#。大多数开发人员都选择一种语言,但可以使用用任何其他支持的语言编写的组件。编译的应用程序逻辑可编译并且可以作为可执行程序运行。在动态编译和预编译模式下均支持。全部页面输出缓存本身并不支持。支持,基于一个或多个URL参数、浏览器类型、自定义函数或任意组合来缓存页面的不同版本。部分页面输出缓存本身并不支持。通过使用用户控件提供内置支持。可使用缓存API和复杂的过期规则来缓存数据和其他对象。数据库访问为市场上的大多数数据库以及开放源代码的数据库提供了驱动程序。直接支持OLE-DB和ODBC,本身还包含了MicrosoftSQLServer™和Oracle的驱动程序。数据库输出数据集作为PHP变量返回,并且可以像任何其他变量那样将其输出。以模板化的方式绑定到服务器端控件以简化开发;如果需要,也可以手动循环。外部组件可以调用各种软件包,并且开发人员可以直接修改Zend引擎(因为它是开放源代码的)。负责Zend的编程人员还可以使.NET对象能够从PHP中调用。充分支持本身的C库和COM对象以及用任何与.NET兼容的语言(包括托管C++[ManagedC++])编写的程序集。对CORBA对象或Java类未提供内置支持。XML/XSLT在附加软件包和库中支持为XMLDOM、XSLT、验证和XML文档的轻量级面向流的分析提供了广泛和易于使用的支持。XMLWebService当前正在开发PHP软件包以支持基于ApacheAXIS引擎以及其他引擎的Web服务。当前版本提供了广泛、灵活、符合标准的支持,使得发布和使用Web服务都非常容易。会话状态基于Cookie的会话管理基于Cookie或无Cookie的会话状态(使用单个服务器内存存储、中央状态服务器或数据库后端)。此外,可扩展的体系结构还允许使用自定义的会话状态模块替换内置选项。要启用无Cookie的会话,只需更改配置。内置功能PHP的内置功能涵盖了基于Web的应用程序可能需要执行的许多常见任务。通过某些额外的处理,它还可以访问Java类库。ASP.NET可以直接访问整个.NETFramework类库,这些类库包含了大量功能。正则表达式支持POSIX和Perl兼容的正则表达式语法。支持Perl-5兼容的正则表达式,以及一些其他功能,例如从右向左匹配、预编译表达式、命名组及完全的Unicode支持。此外,还允许用户指定在正则表达式替换操作过程中调用的函数。调试PHP未提供广泛的调试功能,但可以通过各种第三方产品和Zend增强调试和测试功能。包含广泛的跟踪和环境信息,这些信息可包含在页面中或在单独的页面中显示。使用MicrosoftVisualStudio®.NET除了可以调试客户端脚本和SQLServer存储过程外,还可以轻松地在执行页面时对其进行交互式调试。错误处理不支持错误捕获,但提供了各种错误处理功能和日志。支持结构化的异常处理(其中新增了一个“finally”代码块,无论是否发生错误,都将执行该块),支持引发自定义异常,还支持为不同类型的不可恢复错误指定自定义错误页面。图像处理无内置支持,但可以使用第三方组件。包含大量用于创建和处理图像的工具。(请参阅.NETFramework的代码重用用户定义的函数、创建类的功能以及包含文件。用户控件、服务器控件、自定义类以及包含文件。线程PHP具有很好的线程模型。完全支持。不但可以在单独的线程中同时请求多个页面,而且每个页面(如果需要)还可以生成自己的线程以执行同步或异步操作。数据缓存具有有限的数据缓存(仅限于数据本身)。包含大量的缓存API,能够存储几乎任何类型的数据(包括数据库查询结果),并且能够基于时间、使用情况、文件或其他缓存项而过期。还允许在从缓存中删除给定项时调用用户定义的函数。国际化完全支持Unicode。支持Unicode字符串和各种字符编码。日期、数字和货币函数均可区分文化环境,并根据当前文化环境的设置更改输出(而不要求调用其他函数)。支持使用资源文件对应用程序进行动态本地化。SMTP、HTTP、FTP、POP3本身支持各种Internet协议。SMTP支持依赖于IISSMTP服务。能够很好地支持HTTP。.NET不支持FTP和POP3,但是有一些免费的和销售的第三方组件可用来实现此功能。集成开发环境可以使用大量提供了广泛功能的开发工具,价格从零到几百美元不等。Microsoft提供了一个名为VisualStudioDeveloperCenter。
其他工具(包括BorlandC#Builder和MacromediaDreamweaverMX)也支持ASP.NET。
Web服务器支持支持几乎所有Web服务器。支持IIS以及操作系统支持支持几乎所有常用的操作系统,包括MicrosoftWindows®、Mac、OSX、Amiga、Solaris、FreeBSD、Linux以及AIX等。当前支持Windows2000、WindowsXP和WindowsServer2003。语法和常见任务对比以下各部分比较了PHP和.NET的语法,并介绍了如何完成某些非常常见的编程任务。
注释PHP允许您使用C、C++和Unixshell样式语法在代码中插入注释,注释指示器中的任何内容都不会被执行。
一般来讲,要在ASP.NET中注释出VisualBasic.Net代码,需要使用<%--打开注释块,并使用--%>关闭注释块。
表2显示了这两种环境中的注释。
表2:服务器端注释这是被注释出的
文本块
*/
<%--这是注释
--%>
变量虽然PHP和VisualBasic.NET具有类似的语言构造,但语法却截然不同。由于VisualBasic.NET是基于OOP模型构建的,因而变量的声明要比PHP中变量的声明更严谨(在PHP中声明变量时只需在变量名之前添加一个$符号)。
在VisualBasic.NET中声明变量时,要指定它的变量名和特性。变量的声明语句是Dim关键字。它的位置和内容决定了变量的特性。变量具有级别(例如局部变量和模块变量)、数据类型、生存期以及可访问性。
虽然这种方法最初看上去要比在PHP中指定变量复杂,但实际上它会给开发人员带来方便。ASP.NET致力于帮助开发人员创建可靠的应用程序,而指定数据类型可以使诸如变量清理、调试、异常和错误处理以及代码维护等任务变得更加简单。
表3显示了在两种环境中声明变量的示例。
表3:变量声明$foo
$X
$obj
Dimhead_countASIntegerDimfooAsString
DimXasDate
DimObjasobject
声明数据类型声明语句中的AS子句用于定义所声明变量的数据类型或对象类型。您可以为变量指定以下任意类型:基本数据类型,例如Boolean、Long或Decimal 复合数据类型,例如数组或结构 VisualBasic或其他应用程序中的对象类型或类,例如Label或TextBox
您可以在一个语句中声明多个相同类型的变量而不必重复数据类型。下面的语句将变量numStudents
、numGTA和numProfessors声明为Integer类型:
有关数据类型的详细信息,请参阅Object-OrientedProgramminginVisualBasic。
声明生存期变量的生存期是指变量可供使用的时间段。使用Dim语句声明的局部变量仅在其执行过程中存在。过程终止时,该过程的所有局部变量都将消失,这些变量的值也将丢失。
生存期这个概念很有用,因为它使开发人员在创建应用程序时不必考虑在大型应用程序中出现的许多问题,例如有效的内存管理。通过为变量选择正确的生存期,可以使.NET对未在使用的变量执行清理操作。
有关生存期的详细信息,请参阅Scope。
声明可访问性.NET支持变量的可访问性,从而使开发人员可以控制哪些代码能够访问特定的变量。例如,如果要为某个公式设置一些常数,并且要确保这些常数不会被它们所在类以外的其他代码更改,则可以使用private按如下所示声明该变量:
PrivatemyConstantAsInteger变量的可访问性由声明语句中使用的一个或多个关键字Dim、Public、Protected、Friend、ProtectedFriend或Private确定。开发过程中通常只使用public和private。
您可以使用上述任意关键字来声明模块、结构、类或实例变量。过程中只允许使用Dim关键字,并且可访问性始终为private。
输出PHP中输出数据的典型方式是使用echo()语言构造。ASP.NET中与此最相似的是Response.Write()方法(或<%=%>构造,它只是Response.Write()的简写形式)。表4显示了向页面写入值的基本语法。
表4:基本输出$hello="hihowareyou/n";
echo$hello;
?
>
<%DimHelloAsString="Hihowareyou"&vbcrlf
Response.Write(Hello)
%>
然而,这些用于向浏览器发送输出的方法主要是为了保持与传统ASP的向后兼容性。ASP.NET提供了新的基于控件且面向事件的模型,您只需在服务器控件上设置属性即可将数据输出到浏览器中。通过这种技术可以将布局与代码清楚地分开,从而简化了维护工作,并且在复杂情况下所需的代码要比PHP少得多。
<scriptlanguage="VB"runat="server">SubPage_Load(senderAsObject,eAsEventArgs)TheDate.Text=DateTime.NowEndSub</script>Thecurrentdateis:<asp:Labelid="TheDate"runat="server"/>此示例声明了一个名为TheDate的服务器端标签(Label)控件,并在该页面的Load事件中将此标签的Text属性设置为当前的日期和时间。此代码的HTML输出与其他两个版本相同,不同的是Label控件将自身呈现为span标记(其中包含所设置的任何标签文本)。
条件处理 IF/ELSEPHP具有若干条件处理表达式,例如for、while、switch和foreach,但最常用的是if/else表达式。VisualBasic.NET有几个非常类似的构造,其语法也很类似。表5对PHP和VisualBasic.NET中的等价条件逻辑进行了比较。
表5:基本条件逻辑print"aisbiggerthanb";
}elseif($a==$b){
print"aisequaltob";
}else{
print"aissmallerthanb";
}
Ifa>bResponse.write("aisbigger
thanb")
ElseIfa=bThen
Response.write("aisequalto
b")
Else
Response.write("aissmaller
thanb")
EndIf
切换切换语句是大多数编程语言的常见语言构造,用于通过多个值对单个表达式进行测试。它常用于替换包含多个elseif/else块的if语句。
图6对PHP的switch语句与VisualBasic的SelectCase语句进行了比较。
表6:switch与selectcase语句的对比case0:
print"iequals0";
break;
case1:
print"iequals1";
break;
case2:
print"iequals2";
break;
default:
print"iisnotequalto0,
1or2";
}
SelectCaseNumberiCase0
description="0"
response.write("iequals0")
Case1
description="1"
response.write("iequals1")
Case2
description="2"
response.write("iequals2")
CaseElse
description="iisnotequal
to0,1or2"
response.write("iisnot
equalto0,1or2")
EndSelect
循环另一个非常常见的控制构造是循环。PHP和.NET都支持若干不同的常见循环类型。
表7:For循环print$i;
}
DimsumAsInteger=0DimcounterAsInteger
Forcounter=1To100Step5
sum+=counter
Next
Fori=1to100
Response.write(i)
NextI
在VisualBasic中,这种循环类型被称为For...Next循环,而在PHP中则称为For循环。在此示例中,我们使用了+=运算符作为sum=sum+counter
的简写方式。在PHP中,可以使用Break;语句来中断循环。而For...Next循环可以通过ExitFor语句中断。
只要某个条件计算为true,条件循环便会持续重复一组指令。表8显示了这两种语言中的基本条件循环示例。
表8:条件循环
while($i<=10):
print$i;
$i++;
endwhile;
DimcounteriAsInteger=1DoWhilecounteri<=10
Response.write(i)counteri+=1
Loop
在VisualBasic中,这种循环类型称为Do...Loop语句,或while循环。PHP也支持Do...While循环,该循环与while循环非常类似,不同之处在于它是在每个循环的结尾而不是开始检查真假表达式。Do...While循环与常规while循环的主要差别是前者会确保运行第一个循环(因为只在该循环的结尾检查真假表达式),而常规的while循环则不一定运行。(因为它在每个循环的开始检查真假表达式,如果它一开始便计算为FALSE,该循环将立即结束执行。)
下面给出了一个PHP中这种情况的示例:
$i=0;do{print$i;}while($i>0);此循环只运行一次,因为在第一次循环后检查真假表达式时,表达式计算为FALSE($i不大于0),所以循环将停止执行。
在VisualBasic.NET中,您可以执行同样的操作:
DimcounteriAsInteger=0Doresponse.write(i)counterLoopWhilecounteri>0但是,VisualBasic.NET支持内置的循环功能,这是PHP所不支持的。该功能将对条件进行计算,直到条件为真时为止。
Foreach循环PHP4(而非PHP3)包含一个foreach构造,它与ASP.NET以及某些其他语言中的构造非常类似。它只是为循环数组提供了一个简单的途径。foreach只适用于数组,如果试图将其用于其他数据类型的变量或未初始化的变量,则会导致错误。VisualBasic.NET中与此等价的循环是ForEach...Next语句。表9显示了在这两种语言中循环数组的示例。
表9:Foreach循环foreach($aas$v){
print"/$Key[$i]$v/n";
$i++;
}
foreachvinaresponse.writea(v)(v&vbcrlf)
next
数组PHP中的数组的功能与VisualBasic.NET中的数组的功能截然不同。PHP中的数组实际上是关联数组,但是可以像索引或关联数组那样使用。而VisualBasic.NET中的数组是索引数组。VisualBasic.NET不支持关联数组(但您可以自己创建它们,请参阅下面的“集合”)。其他ASP.NET语言支持这些类型的数组,但VisualBasic.NET并不支持,这可能给PHP开发人员提出了一个难题,因为他们并不习惯使用这种更常见的索引数组,并且可能会希望在VisualBasic.NET中创建关联数组模型。表10显示了PHP和VisualBasic.NET中的简单数组示例。
表10:创建数组的示例
NewInteger(2){0,1,2}
与其他变量一样,VisualBasic.NET数组中的变量也是使用Dim
语句声明的。变量名后面带有一对或多对括号,表明它是数组而不是标量(包含单个值的变量)。
创建VisualBasic.NET数组时,还必须将其声明为保存特定类型的数据。如果指定的类型是Object(作为.NET中所有对象类型的基础的普通类型),则此数组可以保存任何类型的数据,但是从数组中检索值时,必须将值转换为原来的类型。
VisualBasic.NET数组可以是嵌套的数组,也可以是多维数组。VisualBasic.NET中有许多与PHP相对应的用于处理数组的函数,但有一个例外。由于VisualBasic.NET不支持关联数组,因而不存在用于根据数组的“主键”来访问、索引或执行任何操作的函数。VisualBasic.NET中不存在这样的“主键”。
虽然本文多次提到VisualBasic.NET不支持关联数组,但是可以创建集合来代替数组。集合与关联数组有些相似,可以使用集合来解决某些类似的问题。
在某些情况下,将项目存储在集合中要比存储在数组中更有效。
如果要处理一组小型的动态项目,则可以使用集合。要创建集合,只需如下面的示例代码所示声明并实例化一个Collection:
DimmyCollectionAsNewCollection()然后,您可以使用Add方法向集合中添加成员。在此示例中,我们创建了四个字符串并将它们添加到集合中。您还可以选择添加一个唯一的String值作为集合成员的主键。该值作为Add方法的第二个参数传递给集合。
Dimw,x,y,zAsStringw="key1"x="key2"y="key3"z="key4"myCollection.Add(w,"1")myCollection.Add(x,"2")myCollection.Add(y,"3")myCollection.Add(z,"4")虽然这看起来类似于在PHP中创建关联数组,但集合是一种截然不同的事物,因为它本身就是一个对象。对于转到ASP的PHP开发人员,我们建议在尝试在VisualBasic.NET中创建关联数组模型之前先了解一下Microsoft的PHPVisualBasic.NET<?php
$value='somethingfrom
somewhere';
setcookie("TestCookie",
$value,time()+3600);/*
expirein1hour*/
?>
andtoretivethesetcookie
<?
echo$_COOKIE["TestCookie"];
?>
Dimvalueasstring="somethingfromsomewhere"
DimmyCookieAsNewHttpCookie=New
HttpCookie("Somethingfrom
somewhereTestCookie")
DimnowasDateTime=DateTime.Now
myCookie.Value=now.ToString()value
myCookie.Expires=now.AddHour(1)
Response.Cookies.Add(myCookie)
'andtoretrievethesetcookie
Response.Write(Request.Cookies["Whatwe
setTestCookie"}.Value}
设置和检索Session变量ASP.NET中的Session变量与PHP中的Session变量非常类似。这两种环境中的Session变量都为确保Web应用程序访问中的一致性提供了相应处理和Cookie操作。
最重要的一个差别是,当从ASP.NET的Session对象中检索值时,该值将作为普通的System.Object类型返回,而这种类型可以保存任何类型的数据。要使用该值,必须先将其重新转换为原来的基本类型。表12显示了一些Session变量的使用示例。
表12:Session变量的使用
session_start();
session_register('today');
$today=getdate();
?>
<?=$today?>
Session("Today")=DateTime.NowDimtodayAsDate
today=CDate(Session("Today"))
Response.Write(today)
Response.write(session("Today"))
ASP.NET还提供了另一种形式的状态管理,即“应用程序状态”,它与Session变量类似,但只是在应用程序的生存期中保持一致。这使您可以存储各种内容,例如配置信息或数据库连接字符串。这些内容在应用程序运行期间不会发生变化。
有关此主题的详细信息,请参阅《.NETFrameworkDevelopmentGuide》中的.NETFrameworkRegularExpressions。
异常处理ASP.NET框架通过一种人们所熟悉的语言构造Try/Catch提供了结构化的异常处理,从而能够捕获代码中可能出现的异常。PHP没有提供此功能,但PHP5中将添加它。
下面的示例说明了如何在VisualBasic.NET中进行异常处理:
Try'此处是可能导致错误的代码CatcheAsExceptionType'用于处理错误的代码'可选:可在此处放置更多Catch块Finally'始终执行的代码EndTry要注意的是,Try块可以包含一个或多个Catch块,或包含一个Finally块,也可以同时包含两者。也就是说,如果您知道无法更正错误,但仍需要清除某些对象而不管是否发生错误,则可以使用不包含Catch语句的Try...Finally块。
查询数据库在PHP中,通常可以通过两种常见方法访问数据库:使用数据库的特定扩展名或使用独立于数据库的PEARDB库。
在ASP.NET中,可以通过一组称为ADO.NET的对象来访问数据库,这些对象与PEARDB库的功能基本相同。数据库查询实际上是通过一组连接、命令、参数和数据适配器对象完成的。其中的每个对象都有多个版本,具体情况取决于所访问的数据库的类型。例如,有一组对象用于具有OLE-DB驱动程序的数据库(例如MicrosoftAccess),还有一组对象用于具有ODBC驱动程序而没有OLE-DB驱动程序的数据库。针对Oracle和MicrosoftSQLServer也有专门的数据提供者,它们已经过优化,可以分别为每种特定的数据库提供高性能的访问。某些第三方还提供了其他数据库支持,例如MySQL。本节中的示例将使用SQLServer对象,因为它是ASP.NET最常用的数据库。
System.Data、System.Data.SqlClient和System.Data.oledb是用于在ADO.NET中定义数据库访问的命名空间。要使页面能够访问这些类,您需要将System.Data和
图13显示了在这两种语言中执行查询的示例。在PHP中,我们显示了一个使用PEAR的连接,PEAR不仅是用于连接DB的最常用方法之一,但还是与ADO.NET最为类似的方法。
表13:执行查询
//connect
require_once('DB.PHP');
$db=DB::connect
("mysql://mydbvie
w:user@localhost/mydb");
if(DB::iserror($db)){
die($db->getMessage());
$sql="select*frommytable";
$q=$db->query($sql);
if(DB::iserror($q)){
die($q->getMessage());
}
<tr>
<td><?=$row[0]?></td>
<td><?=$row[1]?></td>
<td><?=$row[2]?></td>
</tr>
<scriptrunat="server">SubPage_Load(SenderAsObject,EAs
EventArgs)
DimmyConnectionAsNew
SqlConnection("server=(local)/NetSDK;
database=mydb;Trusted_Connection
=yes")
DimmyCommandAsNew
SqlDataAdapter("select*from
mytable",myConnection)
DimdsAsNewDataSet()
myCommand.Fill(ds,"myDataset")
myDataGrid.DataSource=myDataset
myDataGrid.DataBind()
EndSub
</script>
<%---输出结果---%>
<formrunat="server">
<asp:DataGridid="myDataGrid"
runat="server"/>
</form>
在PHP中,查询结果存储在一个称为resultset(结果集)的变量中,而在ADO.NET中,该变量称为Dataset对象。结果集是返回数据的只读视图,而.NETDataset实际上是返回数据在内存中的读写视图,这使.NET开发人员能够轻松地处理从数据源返回的数据。
输出数据时,ASP.NET提供了若干方法,用于向用户或客户端显示数据。第一种方法与PHP类似,即使用SQLDataReader对象遍历结果集以写出我们要通过查询显示的数据。更常用的方法是ASP.NET的数据绑定(PHP中没有与此对应的方法)。通过该方法,开发人员可以构建用户界面并显示可在应用程序中使用和重用的控件,还可以进一步根据数据和逻辑提取显示内容。数据绑定的语法很灵活,您不仅可以绑定到数据源,还可以绑定到简单的属性、集合、表达式,甚至是方法调用返回的结果。
要使用数据绑定,您需要向某个数据识别服务器控件(例如DataGrid)的DataSource属性指定某个数据源(例如查询结果)。您还可以选择为每个列提供一些附加的格式化信息并调用DataBind()方法。服务器控件将负责完成剩余的工作。
例如,在表13中,我们使用了数据绑定语法输出查询结果,如下所示:
<%---在页面中加载事件---%>myDataGrid.DataSource=myDatasetmyDataGrid.DataBind()<%---输出结果---%><asp:DataGridid="myDataGrid"runat="server"/>数据识别服务器控件将提供其他功能,例如支持对显示的数据进行分页或内联编辑。有关详细信息和示例,请参阅DataBindingServerControls。
数据缓存和页面缓存对经常访问的数据进行缓存可以显著缩短站点的响应时间,因为不需要等待数据库查询便可进行页面处理。而缓存由页面请求生成的HTML可以进一步缩短响应时间,因为根本就无需处理缓存的页面。这两种环境均支持上述两种缓存策略,但与PHP相比,ASP.NET提供了更多用于缓存和管理数据的方法,从而使开发人员可以针对自己应用程序的性能需要选择相应的方法和策略。
页面缓存缓存某个页面请求的HTML输出是减少Web应用程序的负载的一种常用方法。PHP本身不支持页面缓存,但是可以通过编程的方式或下载第三方软件包来执行此操作。通常可以在服务器上通过多种方法执行页面缓存,这些方法可用于缓存编译的代码,直至将页面输出写出到一个单独的文件中(该文件将随代码的更新而更新)。
在ASP.NET中,可以通过低级别的OutputCacheAPI或高级别的@OutputCache指令来执行页面缓存。启用输出缓存后,将在对页面进行第一个GET请求时创建输出缓存条目。后续的GET或HEAD请求将由输出缓存条目支持,直到缓存的请求过期。
输出缓存将检查页面的过期策略和验证策略。如果页面位于输出缓存中并标记了过期策略(指示该页面自缓存时开始60分钟后过期),则60分钟后,该页面将从输出缓存中删除。如果在过期后收到另一个请求,将执行页面代码并再次缓存该页面。这种过期策略称为绝对过期,即页面在某个时间之前有效。
除了对整个页面进行输出缓存外,ASP.NET还提供了一个简单方法,使您可以只缓存页面的特定部分。这种方法称为拆分缓存。您可以使用CachingASP.NETPages。
数据缓存在PHP中,可以通过多种方法以编程方式将查询结果缓存到环境中,但PHP本身并未提供这种方法。在PHP中,可以创建数据缓存类或系统。对于少量信息,只需使用Session变量和/或Cookie;对于大量或复杂的信息,可以创建您自己的数据缓存类。但问题是,当处理包含很多类型的复杂数据时,这种方法的效率会很低且容易出错,在一定程度上会加大编程的难度。
ASP.NET通过Page.Cache对象提供了一个系统范围的数据缓存方法,可用于数据集(DataSet)、数组、集合、XML对象等。对于需要更复杂功能的应用程序,ASP.NET缓存还支持三种特定类型的缓存:过期、清理以及文件和关键项相关性。
过期类型的缓存使开发人员可以控制缓存项目的过期时间。可以将该时间定义为特定的时间(例如01:00),也可以将其定义为相对于上次使用项目时的时间,例如自上次访问该项目时开始20分钟后过期。过期后的项目将从缓存中删除,以后再试图检索该项目时,将返回空值(除非再次将其插入到缓存中)。 清理类型的缓存会在内存不足时尝试删除不经常使用或不重要的项目。开发人员可以控制清理的执行方式,并且可以在将项目插入到缓存中时向清理程序提供提示,以指示创建该项目的相对系统开销以及为使该项目有效而必须对其进行访问的相对频率。 文件和关键项相关性类型的缓存将基于某个外部文件或另一个缓存项目确定该缓存项目的有效性。如果相关项发生变化,缓存项目将失效并从缓存中删除。例如,假设您有一个较大的需要定期更新并下载给员工的报告,则可以在应用程序中使用此功能。应用程序处理文件和报告中的数据,然后缓存该数据并插入对该数据的来源文件(从该文件读取数据)的相关性。当该文件更新时,数据将从缓存中删除,应用程序可以重新读取它并重新插入更新的数据副本。ASP.NET数据缓存为编程人员提供了许多不同的方法来管理应用程序并提高应用程序的响应速度和效率。有关详细信息,请参阅PHPVisualBasic.NET$to="test@atnoaddress.com";
$from=
"me@nosuchaddress.com";
$subject="hi";
$message="justwantedtosay
hi";
mail($to,$subject,$message,
$from)
DimmyMailAsMailMessage=NewMailMessage()
myMail.From="me@nosuchaddress.com"
myMail.To="test@atnoaddress.com"
myMail.Subect="hi"
myMail.Body="justwantedtosayhi"
SmtpMail.Send(myMail)
XML处理和Web服务在PHP中,为分析和处理XML所提供的内置支持功能非常薄弱。虽然开发人员可以用它来分析和处理XML,但它不支持DOM分析(该分析尽管比PHP的SAX分析器速度慢,但更容易使用)。PHP也不支持根据DTD或XMLSCHEME对XML文档进行本地验证,它也不支持XSL/XSLT以及市场上许多Web应用程序常用的各种其他技术。虽然PHP可以通过很多PHP软件包完成许多与XML相关的任务,但.NET和ASP.NET为处理XML提供了广泛的内置支持。XML是.Net平台的核心技术之一。有关Web服务的详细信息,请参阅
利用.NETFrameworkSDK,您可以使用命令行Web服务描述语言工具(WSDL.exe)生成代理类。要为上述示例创建一个名为HelloWorld.cs的代理类,可以输入:
WSDLhttp://someDomain.com/someFolder/HelloWorld.asmx?WSDL此类与前面创建的类非常相似。它包含一个名为SayHelloWorld的方法,用于返回字符串。将此代理类编译到应用程序中,然后调用此代理类的方法,使该代理类通过HTTP将SOAP请求打包并接收SOAP编码的响应,该响应随后被封装为字符串。
对于客户端,该代码是非常简单的,如以下示例所示:
DimmyHelloWorldAsNewHelloWorld()DimsReturnAsString=myHelloWorld.SayHelloWorld()这就是创建一个简单Web服务的全过程。有关XML的一般信息以及Web服务的特定信息,请参阅