Posts Tagged ‘通过’

2个页面间不通过Session与url的传值方式

星期二, 06月 3rd, 2008

下面是全部相关代码,已经编译通过.
Chuandi(传递)是名字空间

WebForm1:
<%@ Page language=”c#” Codebehind=”WebForm1.aspx.cs” Inherits=”chuandi.WebForm1″ %>
<HTML>
<HEAD>
<title>WebForm1</title>
</HEAD>
<body>
<form id=”Form1″ method=”post” runat=”server”>
<asp:TextBox id=”TextBox1″ runat=”server”></asp:TextBox>
<asp:Button id=”Button1″ runat=”server” Text=”传”></asp:Button>
</form>
</body>
</HTML>
using System;
namespace chuandi
{
public class WebForm1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.TextBox TextBox1;
protected System.Web.UI.WebControls.Button Button1;
public string Text1
{
get
{
return this.TextBox1.Text;
}
}
private void Page_Load(object sender, System.EventArgs e)
{}
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Button1.Click = new System.EventHandler(this.Button1_Click);
this.Load = new System.EventHandler(this.Page_Load);
}
private void Button1_Click(object sender, System.EventArgs e)
{
Server.Transfer(”WebForm2.aspx”);
}
}
}


WebForm2:
<%@ Page language=”c#” Codebehind=”WebForm2.aspx.cs” Inherits=”chuandi.WebForm2″ %>
<%@ Reference Page=”WebForm1.aspx” %>
<HTML>
<HEAD>
<title>WebForm2</title>
</HEAD>
<body>
<form id=”Form1″ method=”post” runat=”server”>
<asp:Label id=”Label1″ runat=”server”>Label</asp:Label>
<asp:Button id=”Button1″ runat=”server” Text=”返回”></asp:Button>
</form>
</body>
</HTML>
using System;
namespace chuandi
{
public class WebForm2 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Button Button1;
protected System.Web.UI.WebControls.Label Label1;
public chuandi.WebForm1 wf1;
private void Page_Load(object sender, System.EventArgs e)
{
if(!IsPostBack)
{
wf1=(chuandi.WebForm1)Context.Handler;
Label1.Text=”上页传来de是:” wf1.Text1;
}
}
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Button1.Click = new System.EventHandler(this.Button1_Click);
this.Load = new System.EventHandler(this.Page_Load);
}
private void Button1_Click(object sender, System.EventArgs e)
{
Server.Transfer(”WebForm1.aspx”);
}
}

ASP.NET通过Remoting service上传文件

星期二, 06月 3rd, 2008

最近在因为在学习Remoting,纯粹只是了解一下,发现Remoting确实是好东西.

我通常有三种方式来使用remoting,一种是

第一种:Publishing a public object
公开de对象创建在本地
第二种:Remote creation of a public object (SAO)
对象创建在客户端请求中
第三种:Remote creation of a private object (CAO)
对象创建在HOST上,客户端引用服务器上de对象

目次我也没有很好理解这三种de本质区别在哪里.而这三种方式deremoting创建方式也不相同.

第一种方式
Host:
ChannelServices.RegisterChannel (new TcpChannel(1500));
cTransfer Trans = new cTransfer();
RemotingServices.Marshal (Trans, “TestService”);Client:
cTransfer T = (cTransfer) Activator.GetObject(typeof(cTransfer),
“tcp://host:1500/TestService”);
第二种方式
Host:
ChannelServices.RegisterChannel (new TcpChannel(1500));
RemotingConfiguration.RegisterWellKnownServiceType(typeof(cTransfer),
“TestService”, WellKnownObjectMode.Singleton);Client:
cTransfer T = (cTransfer) Activator.GetObject(typeof(cTransfer),
“tcp://host:1500/TestService”);
第三种方式
Host:
ChannelServices.RegisterChannel (new TcpChannel(1500));
RemotingConfiguration.RegisterActivatedServiceType(typeof(cTransfer));Client:
object[] attr = {new UrlAttribute(”tcp://host:1500″)};
object[] args = {”Sample constructor argument”};
cTransfer T = (cTransfer) Activator.CreateInstance(typeof(cTransfer), args, attr);
如果我需要一个对象(object)允许远程调用处理,那么这个对象(object)需要继承于MarshalByRefObject这个类.

如何在remoting中传送文件呢?基本思路就是在client打开clientde文件,转换在Byte[]类型之后调用hostde对象.
Client与Host之间传送de对象
[Serializable]
public struct kAction
{
public string filename;
public byte[] context;
};打开文件,将流字节保存到Context中去
Stream fileStream=File.Open(this.transFileName.Text,FileMode.Open);
fileStream.Position=0;
byte[] Content = new byte[((int) fileStream.Length) 1];
fileStream.Read(Content,0,Content.Length) ;
在Host在读取到Kaction之后,把它保存到指定文件夹下面
MemoryStream meoeryStream=new MemoryStream(k_Action.context);
FileStream fileStream=new FileStream(@”d:\” k_Action.filename,FileMode.Create);
meoeryStream.WriteTo(fileStream);
fileStream.Close();
meoeryStream.Close();
发现不能在对象中又定义新de对象.在准备发送到HOST上会提示“包含潜在危险de类型”.
[Serializable]
public struct kAction
{
public string filename;
public byte[] context;
public FineInfo fileInfo;//这里

};
记录一下自己de心得.有空我会好好整理下下回做篇完整点de.

cnzc’s blogs

通过JSP的预编译消除性能瓶颈

星期一, 06月 2nd, 2008

欢迎来到“管理”这个版,新一期de月刊专栏专注于 WebLogic 服务器de管理、配置、处理和开发方面.

开辟这个专栏de目de是为了向大家介绍在使用WebLogic Sever时,能普遍用到de非J2EE开发方面de问题.开发者和管理者同样会发现这个专栏非常有价值,因为这些文章既适用于开发又适用于最终产品de应用.此外,它很大程度上利用了来自于该领域和工程实验室de经验,它提供了对实际问题de详细解答.

JSP预编译de必要性

本月de文章着眼于移除潜在de系统性能瓶颈,它通过解决一个最普通de问题――在服务器运行时间中deJSP (JavaServer Page)编译de系统开销问题,这个问题困扰着几乎所有deJ2EE发展计划.虽然JSP是在J2EE应用范围内呈现动态HTML视图de理想选择,但在某种程度上它们会影响性能,这比错误de更令人讨厌,给人de第一感觉是该程序很慢.
根据J2EE规范,JSP主要是HTML文件,在它里面包含着Java相关代码用来和其他de系统组件进行交互以及动态de显示信息.规范规定所有deJ2EE编译应用服务器应当支持JSP,客户请求一个特定deJSP,将:

转换JSPHTML格式成为servlet类型deJava类(Java源格式),用简写deJSP符号代替完全符合规定deJava语法

将新产生deJava源文件编译成.class字节码形式

在新编译de类上执行适当de接口方法并且对客户端请求返回响应.

虽然从发展de观点来看对于在表示层内管理动态HTMLde产生这是最好de途径,但它影响到服务器de运行时间环境,要求JSP被解析、转变成Java相关代码,并且在它去处理一个特定de客户端请求之前被编译.对最终用户明显de影响是,一个响应将会被延迟知道给定deJSP文件被编译通过.考虑到一个特定de用户请求可能用到两个或多个JSP文件,因此编译状态必需de时间增加了很多倍.

对第一个请求一个特定deJSP页面并且迫使被请求de文件进行初始编译de终端用户,会感觉应用程序很慢并且没有响应. 虽然这样de感觉可能存在,但是对于特定deJSP文件de编译过程通常在给定de应用服务器虚拟机实例de生命周期中完成一次. 因此,它对性能总体上de影响被考虑成一种障碍,而不是对应用程序总响应时间de一个严重de障碍.然而,在生产环境中为了传送基于JSPdeJ2EE应用程序de生产系统,必须克服JSPde缺陷并且对最终用户进行透明de编译.

这样,生产环境如何能受益于JSP文件,还要避免运行时编译de性能打击答案是简单de:执行一个一般作为JSP预编译de过程. 借用JSP预编译,已经被预编译de在脱机环境中deJSP文件和他们de编译结果被部署在生产环境中.如果结果类文件de预编译和部署正确de完成,应用程序服务器将会为JSP文件运行先前de编译类,并且在运行中将不强制对特定de请求进行再编译. 这样产生了一种情况,应用程序de操作避免了多余de编译开销,允许系统管理员移除对系统总性能会造成影响de一个已知de瓶颈.
不同de方法论和途径

没有人怀疑JSP预编译de承诺听起来令人兴奋. 然而,为了要实现这样de承诺,您必须首先了解能够执行这个技术de不同途径,以及它们各自优点和缺点.

运行应用程序进行强制预编译

用于实现JSP预编译最显而易见de方法是在产品发布前,通过请求在应用程序中de所有可能deJSP页面,因此编译在终端用户访问站点前完成.它既可以通过第一次人工浏览整个站点时完成也可以通过从测试系列应用程序或其他脚本语言de客户端(例如LoadRunner SilkPerformer)发动自动请求来实现. 当使用这种方法(可能是所有deJSP预编译方法中de最简单de而又较下策de一个方法)时,他de缺点很快就显现出来了.也许最大de缺点是很难实现跨集群环境,在集群环境中,用该方法对于单一节点de实例发送de请求依集群中de节点数量成倍de增加.而且,当这个集群是由一个或更多deWeb服务器或硬件负载权衡者来代理时,更难保证在一个集群de环境中每个服务器实例都进行JSP预编译,因为一般没有方法来搞清代理最初把请求转到哪个应用服务器.此外,在应用服务器每次重启时,这个方法必须执行,当站点很小时,不能一次实现所有de编译就会很痛苦.因此,我不推荐这种JSP预编译de方法.

使用编译工具来实现预编译

因为人工执行一个站点应用程序来强制JSP预编译在真实de产品环境中是一个较大de缺点,在预编译运行期间选择编译JSP,使其变成为servlets变得更令人心动.幸运地,WLS提供了二个方法.第一种方法在服务器启动部署一个特定deWeb应用程序de时候执行预编译(declarative预编译),第二种方法是命令行Java工具(weblogic.jspc)允许过程在完全脱机de情况下处理(程序方式de预编译).两种方法都有它们de优点,程序方式de预编译在两者中有更灵活de选项,并且提供更让人无法抗拒de理由来使用它.

DECLARATIVE预编译

对于在WLS下公布de预编译,一个特定deWeb应用程序(独立de或者作为EARde一部分)能够被配置,因此所有deJSP在应用程序部署(服务器启动时)和重新部署(运行时)期间里被预编译.对WEB-INF/ weblogic.xml部署描述符要做必要de配置变化,使用预编译<jsp-param/>指令,如下:
<weblogic-web-app>

<jsp-descriptor>
<jsp-param>
<param-name>precompile</param-name>
<param-value>true</param-value>
</jsp-param>
</jsp-descriptor>

</weblogic-web-app>

在一个特定deWeb应用程序上进行部署(或重新部署),如果上述de参数被设定成真, WLS 将会在WAR内尝试预编译所有deJSP文件,在程序中从 Web 应用程序de根目录下循环de运行它de方法( 略过Web-INF) .以. jsp .JSP为扩展名de文件都变成了编译de对象. 被编译后de文件被以适当de包目录结构形式被放置在Web 应用程序de临时工作目录下面(默认在Web-INF子目录中,除非在 weblogic.xml 里有特别说明).

这个方法是到目前为止进行JSP预编译最方便de途径(“flick-a-switch” 途径),他有许多指出来毫无意义de缺点.如果一个错误在JSPde编译期间或在部署(或重新部署) de时候发生,Web 应用程序de预编译将会在例外处暂停.另外,如果在一个特定deWeb应用程序里面有许多JSP文件de情况,declarative预编译显著de影响着部署时间,阻断部署直到所有de文件都被编译.对于大型de应用程序,当出现数以百计deJSP 文件以declarative预编译被执行de时候,这种部署时间趋向以分钟来计算 (在某些情况1015分钟,其他情况可能更长时间).设想开始一个服务器实例,在一个特定deWeb应用程序周期内进入部署状态用declarative 预编译激活.如果在应用内有很多deJSP文件以及部署,接近完成时就已经花费了大量de时间,在编译期间由于抛出一个例外而突然失败,当然会引起挫折感.虽然起先看起来比较方便,但declarative 编译对生产系统管理造成重大de风险,因此应该在经过慎重de考虑后再使用它.

程序方式de预编译

WLS下最可靠de预编译JSPde方法是使用Java命令行,weblogic.jspc,它位于WLS安装delib目录之下deweblogic.jar文件中.这个工具允许开发者在发展阶段和在部署前解决编译时间问题de时候编译需要deJSP文件.它也为生产系统提供一个有能力实现JSP预编译de管理员.这种用法de主要好处是:

文件可以被预编译一次然后可以被多次部署.(这不被服务器实例de重复利用所影响)

编译时de例外可以被预先解决而不影响部署.

类可以通过集群部署.

使用weblogic.jspcde缺点是需要人工干涉,并且它在开发时并当在JSP文件变得过时de时候必须被重新运行.然而,考虑到前面de两个方法de讨论,我几乎不能将这种不方便当成该方法de一个缺点,因此推荐它作为最可靠和最灵活de机制来实现JSP预编译.

执行weblogic.jspc

为了更有效de使用weblogic.jspc,您必须首先了解它de用法和语法.这篇文章我将利用WLS6.1 SP2de工具de功能.注意:下面给出de语法和最好de惯例应该应用于WLS 6.1de所有版本以及新deWLS 7.0.

为了调用命令行JSP编译器(weblogic.jspc),您必须确定下面de内容:

PATH环境变量必须包含您机器上安装deJ2SE1.3包de二进制目录(例如,/opt/j2se/1.3.1/sdk/bin 或者c:\sunsoft\j2se\1.3.1\sdk\bin),以获得JVM运行时de支持.如果您打算使用javac作为您deJSP编译deJava编译器,要确定PATH包含全部Java 1.3 de软件开发工具包(SDK)de二进制目录,并且不仅仅是JRE(Java Runtime Engine,Java运行时间引擎),因为没有编译器和JRE关联. 如果您打算使用一个编译器而不是javac(例如 Jikes),也要为那个编译器确定在PATH中包含正确de目录.

设置Java系统类路径用来包含来自WLS 6.1 SP2 安装目录deweblogic.jar文件,通过在产品库目录下默认建立(例如,/opt/bea/wlserver6.1/lib/weblogic.jar或者c:\bea\wlserv -er6.1\lib\weblogic.jar).此外,请确定在JSP编译阶段中您可能需要de参考类(JAR或类文件)也在您de类路径中.

在第一次执行weblogic.jspc之前,您需要测试您de命令行配置是否是按上述配置.它可以通过简单运行一个WLS版本检查来完成,使用命令“java weblogic.version”,这个命令应该返回下面de内容:
which should return the following:
WebLogic Server 6.1 SP2 12/18/2001 11:13:46
#154529
WebLogic XML Module 6.1 SP2 12/18/2001
11:28:02 #154529

如果您de输出和上面de不相似(和您运行de版本相对应),在进行JSP预编译前,要重新访问PATH和类路径变量将其设置成您de当前命令行环境.
一般deweblogic.jspcde语法如下面给出de:
java weblogic.jspc [options] <jsp files>…

在一个编译器de单一调用中默认情况下JSP编译器可以编译一个JSP文件或一组JSP文件,并且可以通过设置命令行选项,编译器可以以不同de方法工作.下面给出一个例子:
java
weblogic.jspc
-webapp mywebapp
-compiler javac
-compileFlags “-g”
-classpath /u/apps/dist/src/lib.jar
-d .
-package com.slackwerks.mywebapp.jsp
-commentary
-keepgenerated
-k
mywebapp\index.jsp

这篇文章只列举了一个例子,如果您要想更加了解weblogic.jspc如何能在您de环境中使用和管理de话,请参阅www.slackwerks.com/wldj,我提供了对整套de工作选项,使用de含义以及相关联问题de讨论.

结论

虽然关于JSP预编译de问题较多,但许多de途径可以解决.然而,考虑到上文所说de那些优点和缺点,应该较容易de看出经由weblogic.jspc预编译de程序方式是为克服JSP固有de缺点de一个灵活de选项.在开发阶段de早期,熟悉该工具将改善生产期间应用程序de管理和性能状况.

通过JDBC连接oracle数据库的十大技巧

星期一, 06月 2nd, 2008

Java数据库连接(JDBC)API是一系列能够让Java编程人员访问数据库de接口,各个开发商de接口并不完全相同.在使用多年deOracle公司deJDBC后,我积累了许多技巧,这些技巧能够使我更好地发挥系统de性能和实现更多de功能.
  1、在客户端软件开发中使用Thin驱动程序
  在开发Java软件方面,Oraclede数据库提供了四种类型de驱动程序,二种用于应用软件、applets、servlets等客户端软件,另外二种用于数据库中deJava存储过程等服务器端软件.在客户机端软件de开发中,我可以选择OCI驱动程序或Thin驱动程序.OCI驱动程序利用Java本地化接口(JNI),通过Oracle客户端软件与数据库进行通讯.Thin驱动程序是纯Java驱动程序,它直接与数据库进行通讯.为了获得最高de性能,Oracle建议在客户端软件de开发中使用OCI驱动程序,这似乎是正确de.但我建议使用Thin驱动程序,因为通过多次测试发现,在通常情况下,Thin驱动程序de性能都超过了OCI驱动程序.
  2、关闭自动提交功能,提高系统性能
  在第一次建立与数据库de连接时,在缺省情况下,连接是在自动提交模式下de.为了获得更好de性能,可以通过调用带布尔值false参数deConnection类desetAutoCommit()方法关闭自动提交功能,如下所示:
  conn.setAutoCommit(false);
  值得注意de是,一旦关闭了自动提交功能,我就需要通过调用Connection类decommit()和rollback()方法来人工de方式对事务进行管理.
  3、在动态SQL或有时间限制de命令中使用Statement对象
  在执行SQL命令时,我有二种选择:可以使用PreparedStatement对象,也可以使用Statement对象.无论多少次地使用同一个SQL命令,PreparedStatement都只对它解析和编译一次.当使用Statement对象时,每次执行一个SQL命令时,都会对它进行解析和编译.这可能会使您认为,使用PreparedStatement对象比使用Statement对象de速度更快.然而,我进行de测试表明,在客户端软件中,情况并非如此.因此,在有时间限制deSQL操作中,除非成批地处理SQL命令,我应当考虑使用Statement对象.
  此外,使用Statement对象也使得编写动态SQL命令更加简单,因为我可以将字符串连接在一起,建立一个有效deSQL命令.因此,我认为,Statement对象可以使动态SQL命令de创建和执行变得更加简单.
  4、利用helper函数对动态SQL命令进行格式化
  在创建使用Statement对象执行de动态SQL命令时,我需要处理一些格式化方面de问题.例如,如果我想创建一个将名字O’Reilly插入表中deSQL命令,则必须使用二个相连de“””号替换O’Reilly中de“’”号.完成这些工作de最好de方法是创建一个完成替换操作dehelper方法,然后在连接字符串心服用公式表达一个SQL命令时,使用创建dehelper方法.与此类似de是,我可以让helper方法接受一个Date型de值,然后让它输出基于Oracledeto_date()函数de字符串表达式.
  5、利用PreparedStatement对象提高数据库de总体效率
  在使用PreparedStatement对象执行SQL命令时,命令被数据库进行解析和编译,然后被放到命令缓冲区.然后,每当执行同一个PreparedStatement对象时,它就会被再解析一次,但不会被再次编译.在缓冲区中可以发现预编译de命令,并且可以重新使用.在有大量用户de企业级应用软件中,经常会重复执行相同deSQL命令,使用PreparedStatement对象带来de编译次数de减少能够提高数据库de总体性能.如果不是在客户端创建、预备、执行PreparedStatement任务需要de时间长于Statement任务,我会建议在除动态SQL命令之外de所有情况下使用PreparedStatement对象.
  6、在成批处理重复de插入或更新操作中使用PreparedStatement对象
  如果成批地处理插入和更新操作,就能够显著地减少它们所需要de时间.Oracle提供deStatement和 CallableStatement并不真正地支持批处理,只有PreparedStatement对象才真正地支持批处理.我可以使用addBatch()和executeBatch()方法选择标准deJDBC批处理,或者通过利用PreparedStatement对象desetExecuteBatch()方法和标准deexecuteUpdate()方法选择速度更快deOracle专有de方法.要使用Oracle专有de批处理机制,可以以如下所示de方式调用setExecuteBatch():
PreparedStatement pstmt3D null;
try {
((OraclePreparedStatement)
pstmt).setExecuteBatch(30);

pstmt.executeUpdate();
}

  调用setExecuteBatch()时指定de值是一个上限,当达到该值时,就会自动地引发SQL命令执行,标准deexecuteUpdate()方法就会被作为批处理送到数据库中.我可以通过调用PreparedStatement类desendBatch()方法随时传输批处理任务.
  7、使用Oracle locator方法插入、更新大对象(LOB)
  OracledePreparedStatement类不完全支持BLOB和CLOB等大对象de处理,尤其是Thin驱动程序不支持利用PreparedStatement对象desetObject()和setBinaryStream()方法设置BLOBde值,也不支持利用setCharacterStream()方法设置CLOBde值.只有locator本身中de方法才能够从数据库中获取LOB类型de值.可以使用PreparedStatement对象插入或更新LOB,但需要使用locator才能获取LOBde值.由于存在这二个问题,因此,我建议使用locatorde方法来插入、更新或获取LOBde值.
  8、使用SQL92语法调用存储过程
  在调用存储过程时,我可以使用SQL92或Oracle PL/SQL,由于使用Oracle PL/SQL并没有什么实际de好处,而且会给以后维护您de应用程序de开发人员带来麻烦,因此,我建议在调用存储过程时使用SQL92.
  9、使用Object SQL将对象模式转移到数据库中
  既然可以将Oraclede数据库作为一种面向对象de数据库来使用,就可以考虑将应用程序中de面向对象模式转到数据库中.目前de方法是创建Java bean作为伪装de数据库对象,将它们de属性映射到关系表中,然后在这些bean中添加方法.尽管这样作在Java中没有什么问题,但由于操作都是在数据库之外进行de,因此其他访问数据库de应用软件无法利用对象模式.如果利用Oraclede面向对象de技术,可以通过创建一个新de数据库对象类型在数据库中模仿其数据和操作,然后使用JPublisher等工具生成自己deJava bean类.如果使用这种方式,不但Java应用程序可以使用应用软件de对象模式,其他需要共享您de应用中de数据和操作de应用软件也可以使用应用软件中de对象模式.
  10、利用SQL完成数据库内de操作
  我要向大家介绍de最重要de经验是充分利用SQLde面向集合de方法来解决数据库处理需求,而不是使用Java等过程化de编程语言.
  如果编程人员要在一个表中查找许多行,结果中de每个行都会查找其他表中de数据,最后,编程人员创建了独立deUPDATE命令来成批地更新第一个表中de数据.与此类似de任务可以通过在set子句中使用多列子查询而在一个UPDATE命令中完成.当能够在单一deSQL命令中完成任务,何必要让数据在网上流来流去de?我建议用户认真学习如何最大限度地发挥SQLde功能.

JSP由浅入深(3)—— 通过表达式增加动态内容

星期一, 06月 2nd, 2008

在我前面de章节中,任何deHTML文件都可以转变成JSP文件,做法是通过改变它de扩展名为.jsp.当然,我要知道是什么使得JSP有用呢?答案是嵌入Javade能力.将下列文本放置在一个以.jsp为扩展名de文件中,比如说这个文件为myjsp.jsp,然后将这个文件放置到您deJSP目录下并且在浏览器上看它.以下是具体de相关代码:
<HTML>
<BODY>
Hello! The time is now <%= new java.util.Date() %>
</BODY>
</HTML>
这里要注意,每次您在浏览器中重载网页de时候,它就出现当前时间.字符系列<%= and %>de作用是圈起Java表达式,这个表达式将在运行de时候被计算.
正因为这样,使用JSP产生动态HTML网页来响应用户de动作才变为可能.
好吧,教程结束之后您最好作个练习:为不同de系统属性编写一个JSP用来输出由System.getProperty返回de数值,比如java.version、java.home、os.name、user.home以及user.dir等等.

怎样在PHP中通过ADO调用Asscess数据库和COM程序

星期一, 06月 2nd, 2008

作者: John Lim.
翻译: znsoft(http://www.phpease.com znsoftm@21cn.com)
PHP4已经支持MicrosoftdeCOM技术.然而文档中在COM部分却提得很少.
这儿是几个我试过de例子.希望这些给您一些概念.注意de是这些只能运行在32位deMicrosoft Windows平台下.
用php激活ADO
ADO是Microsoftde数据库对象技术.ADO里面包括连接数据库de对象,从查询语句中返回数据de记录集对象和表现数据元素de字段对象.
许多数据库不直接支持ADO.代之de是很多数据库支持低两级deMicrosoft数据库技术:ODBC和OLEDB.许多数据库支持ODBC;但OLEDB有比ODBC更快de名声.
ADO则是包装ODBC和OLEDBdeAPI.
这个例了打开一个新deADO连接对象,对过ODBC打开一个传统deACCESS数据库,然后我执行SQL查询,会返回一个记录集对象.然后我显示记录集de前三个字段.

<?
$dbc = new COM("ADODB.Connection");
$dbc->Provider = "MSDASQL";
$dbc->Open("nwind");
$rs = $dbc->Execute("select * from products");
$i = 0;
while (!$rs->EOF) {
$i = 1;
$fld0 = $rs->Fields(0);
$fld1 = $rs->Fields(1);
$fld2 = $rs->Fields(2);
print "$fld0->value $fld1->value $fld2->value<BR>";
$rs->MoveNext();
}
$rs->Close();
?>

用PHP调用Microsoft Word
这是另一个例子:
<?
$word=new COM("word.application") or die("Cannot start Microsoft Word");
print "Loaded word version ($word->Version)\n";
$word->visible = 1 ;
$word->Documents->Add();
$word->Selection->Typetext("This is a test");
?>

通过文字传递创建的图形按钮

星期一, 06月 2nd, 2008

通过文字传递创建de图形按钮,详细说明请看文内英文说明
<?php Header( "Content-type: image/gif"); // info for the browser
/* PHP3 Button generator, (c) 2000 by IzzySoft (izzysoft@buntspecht.de)
* License: GPL (and it would be nice to drop me a note that you find it
* useful - if you use it. And, of course, I am very interested in
* enhancements you made to the script!
*
* Purpose: generate buttons with text passed by parameter.
*
* possible parameters to the script:
*button- input gif image. Just the part of the filename before the dot.
*The specified image file is expected in the same directory
*as this script resides in.
*font - font to use (1 - 5; 1 is very small, 3 medium, 5 normal size.
*The script will automatically use a smaller font if text is
*too long for selected size.) Default: 5
*text - the text to be put on the button. Will be centered.
*textcolor - color for the letters. Default: white.
*in this example code only blue, white and black are defined;
*but you can add custom colors easily.
*width,heigth - width and heigth of the button. Useful only if target
*button should have different size than source image.
*
* Example for usage:
* <IMG SRC="button.php3?button=yellow&text=Example">
* will look for yellow.gif and put the string "Example" on it.
*
* I use to have three buttons I normally generate (one displays selected
* item, one is for mouseover(), and one is the default button). The source
* images are yellow.gif, white.gif and blue.gif - so my script assumes
* blue.gif as default if "button=" not specified - you may wish to change
* this below, it’s easy ;)
*/
// ===========================[ check fo
// r parameters and/or set defaults ]===
if (($font == "") || ($font > 5) || ($font < 1)) { $font = 5; }
if ($text == "") { $text="Moin!"; }// button text
if ($textcolor == "") {// color for the letters
switch ($button) {
case "yellow":
case "white":
$textcolor = "black";
break;
default:
if ($button == "") { $button = "blue"; }
$textcolor = "white";
break;
}
} // textcolor end
$im_info = getimagesize("$button.gif"); // button size
if ($width == "") {
if ($im_info == "") {
$buttonwidth = 125;
} else {
$buttonwidth = "$im_info[0]";
}
} else {
$buttonwidth = $width;
}
if ($heigth == "") {
if ($im_info == "") {
$buttonheigth = 30;
} else {
$buttonheigth = "$im_info[1]";
}
} else {
$buttonheigth = $heigth;
}
$vmidth = ceil($buttonheigth / 2);
// =====================================
// ===[ now lets define some colors ]===
$white = "255,255,255";
$black = "0,0,0";
$blue = "0×2c,0c6d,0xaf";
// =====================================
// =============[ build color array ]===
// now we put the needed color into an a
// rray (if e.g. "$textcolor=white",
// the array $textcolor_array represents
// "white")
$textcolor_array = explode(",", $$textcolor);
// =======================[ calculate po
// sition of the text on the button ]===
do {
$textwidth = strlen($text) * imagefontwidth($font);
$x = ($buttonwidth - $textwidth) / 2; $x = ceil($x);
$y = $vmidth - (imagefontheight($font) / 2);
$font–;
} while (($x < 0) && ($font > 0)); $font ;
// =====================================
// ======[ now we create the button ]===
if (isset($width) || isset($heigth)) {// size change expected?
$ima = imagecreatefromgif("$button.gif");// open input gif
$im = imagecreate($buttonwidth,$buttonheigth); // create img in desired size
$uglybg = ImageColorAllocate($im,0xf4,0xb2,0xe5);
ImageRectangle($im,0,0,$buttonwidth,$buttonheigth,$uglybg);
$dummy = imagecopyresized($im,$ima,0,0,0,0,$buttonwidth,$buttonheigth,$im_info[0],$im_info[1]);
if ($dummy == "") {
ImageDestroy($im); // if it didn’t work, create default below instead
} else {;}
ImageDestroy($ima);
ImageColorTransparent($im,$uglybg);
} else {
$im = imagecreatefromgif("$button.gif");// open input gif
}
if ($im == "") { $im = imagecreate($buttonwidth,$buttonheigth); // if input gif not found,
$rblue = ImageColorAllocate($im, 0×2c,0×6D,0xAF);// create a default box
ImageRectangle($im,0,0,200,100,$rblue);
}
$color = ImageColorAllocate($im, $textcolor_array[0], $textcolor_array[1], $textcolor_array[2]); // allocate the color
imagestring($im, $font, $x, $y, "$text", $color); // put the text on it
ImageGif($im);// send button to browser
ImageDestroy($im);// free the used memory
?>

通过html表格发电子邮件

星期一, 06月 2nd, 2008

如下:
<?
/******************************************************************************
Description: This is a simple script to send emails via a html-form
to different users
Date : 1999-02-25
Author : amalesh kempf <amalesh@goatrance.de>

Create this table
The field "what" is for different categories
CREATE TABLE email_notify (
ID int(11) DEFAULT ‘0′ NOT NULL,
What varchar(60) DEFAULT ‘0′ NOT NULL,
Name varchar(60) DEFAULT ‘0′ NOT NULL,
Email varchar(60) DEFAULT ‘0′ NOT NULL,
timestamp varchar(16),
KEY (What),
PRIMARY KEY (ID));
To fill this table you might create an insert form
*******************************************************************************/

// Set this values:
$strHost ="localhost";
$strUser ="root";
$strPassw ="";
$strSender="you@domain.com";

if (!$btnSendEmail)
{
?>
The email will be added automatically with "Hello Name" in the first line of
the emailbody!<br>
<br>
<form action="send_email.php3" enctype="application/x-www-form-
urlencoded" method="post">
<table>
<tr>
<td>Subject</td>
<td><input name="strSubject" size="40"></td>
</tr>
<tr>
<td>Body</td>
<td><textarea cols="40" name="strBody" rows="8"
wrap="PHYSICAL"><? echo $strBody ?></textarea></td>
</tr>
<tr>
<td>Category</td>
<td>
<select name="strWhat">
<?php // add you categories here: ?>
<option value="party">Party</option>
</select>
</td>
</tr>
</table>
<input name="btnSendEmail" style="HEIGHT: 24px; WIDTH: 224px"
type="submit" value="Sende email">
</form>
<?php
}

if (isset($btnSendEmail))
{ echo "Send Email<br>";
// Create connection
$intConID = mysql_pconnect($strHost,$strUser,$strPassw);
// Header
$strHeader = "Return-Path: $strSender\nErrors-To: $strSender\nFrom:
$strSender";
// SQL
$strSQL = "select name,email from email_notify where lcase(what) =
‘$strWhat’";
$intRes = mysql_query($strSQL,$intConID);
echo "Send Email $strBody<br>";
// fetch array
while($saRow = mysql_fetch_array($intRes))
{ $strEmail = $saRow["email"];
$strName = $saRow["name"];
$strBodyComplete = "Hello " . $strName[$i] . "!\n\n" . $strBody;
// Email
mail($strEmail,$strSubject,$strBodyComplete,$strHeader);
// Output
echo "Send to $strName<br>";
}
}
?>

通过ODBC连接的SQL SERVER实例

星期一, 06月 2nd, 2008

通过ODBC连接deSQL SERVER实例一
<?
$connection = odbc_connect("mydata","userid","passwd");
$query = "select * from tab_1 where no>0" ;
$result = odbc_do($connection,$query) ;
print "<table border=’1′ width=’100%’ id=’tab1′ cellPadding=’1′ cellSpacing=’0′ align=’top’ bordercolorlight=’#008000′ bordercolordark=’#008000′>";
while(odbc_fetch_into($result,&$fields))
{
print "<tr>\n";
for ($i = 21; $i <= 31 ; $i ) {
print "<td width=’6%’><input style=’BACKGROUND-COLOR: #ffffff; BORDER-BOTTOM: #000000 1px solid; BORDER-LEFT: #ffffff 1px solid; BORDER-RIGHT: #ffffff 1px solid; BORDER-TOP: #ffffff 1px solid; BORDER-BOTTOM: #ffffff 1px solid; COLOR: #000000; FONT-SIZE: 9pt’ size=’7′ type=’text’ name=text$i value=$temp>";
}
}
print "</table>";
odbc_close($connection);
?>

通过对服务器端特性的配置加强php的安全

星期一, 06月 2nd, 2008

作者:san < xuzhikun@nsfocus.com >
主页:http://www.nsfocus.com
日期:2001-11-15
前面象Shaun Clowes和rfp等都比较详细de介绍了php、cgi程序在编程过程中遇到 de问题,以及如何通过应用程序漏洞突破系统,这篇文章我来通过对phpde一些服务器端特性来进行配置加强phpde安全.写 cgi脚本de时候我de确一定注意各种安全问题,对用户输入进行严格de过滤,但是常在岸边走哪有不湿鞋 ,吃烧饼哪有不掉芝麻,人有失蹄马有失手,连著名dephpnuke、phpMyAdmin等程序都出现过很严重de 问题,更何况象我等小混混写de脚本.所以现在我假设php脚本已经出现严重问题,比如象前一阵子 phpnukede可以上传php脚本de大问题了,我如何通过对服务器de配置使脚本出现如此问题也不能突破 系统.
1、编译de时候注意补上已知de漏洞
从4.0.5开始,phpdemail函数加入了第五个参数,但它没有好好过滤,使得php 应用程序能突破safe_modede限制而去执行命令.所以使用4.0.5和4.0.6de时候 在编译前我需要修改php源码包里
ext/standard/mail.c文件,禁止mail函数de第五参数或过滤shell字符.在mail.c
文件de第152行,也就是下面这行:
if (extra_cmd != NULL) {
后面加上extra_cmd=NULL;或extra_cmd = php_escape_shell_cmd(extra_cmd);
然后编译php,那么我就修补了这个漏洞.
2、修改php.ini配置文件
以php发行版dephp.ini-dist为蓝本进行修改.
1)Error handling and logging
在Error handling and logging部分可以做一些设定.先找到:
display_errors = On
php缺省是打开错误信息显示de,我把它改为:
display_errors = Off
关闭错误显示后,php函数执行错误de信息将不会再显示给用户,这样能在一
定程度上防止攻击者从错误信息得知脚本de物理位置,以及一些其它有用de 信息,起码给攻击者de黑箱检测造成一定de障碍 .这些错误信息可能对我 自己有用,可以让它写到指定文件中去,那么修改以下:
log_errors = Off
改为:
log_errors = On
以及指定文件,找到下面这行:
;error_log = filename
去掉前面de;注释,把filename改为指定文件,如
/usr/local/apache/logs/php_error.log
error_log = /usr/local/apache/logs/php_error.log
这样所有de错误都会写到php_error.log文件里.
2)Safe Mode
phpdesafe_mode功能对很多函数进行了限制或禁用了,能在很大程度解决phpde
安全问题.在Safe Mode部分找到:
safe_mode = Off
改为:
safe_mode = On
这样就打开了safe_mode功能.象一些能执行系统命令de函数shell_exec()和“ 被禁止,其它de一些执行函数如:exec(), system(), passthru(), popen() 将被限制只能执行safe_mode_exec_dir指定目录下de程序.如果您实在是要 执行一些命令或程序,找到以下:
safe_mode_exec_dir =
指定要执行de程序de路径,如:
safe_mode_exec_dir = /usr/local/php/exec
然后把要用de程序拷到/usr/local/php/exec目录下,这样,象上面de被限制
de函数还能执行该目录里de程序.
关于安全模式下受限函数de详细信息请查看php主站de说明:
http://www.php.net/manual/en/features.safe-mode.php
3)disable_functions
如果您对一些函数de危害性不太清楚,而且也没有使用,索性把这些函数禁
止了.找到下面这行:
disable_functions =
在”=“后面加上要禁止de函数,多个函数用”,“隔开.
3、修改httpd.conf
如果您只允许您dephp脚本程序在web目录里操作,还可以修改httpd.conf文件限 制phpde操作路径.比如您deweb目录是/usr/local/apache/htdocs,那么在
httpd.conf里加上这么几行:
<Directory /usr/local/apache/htdocs>
php_admin_value open_basedir /usr/local/apache/htdocs
</Directory>
这样,如果脚本要读取/usr/local/apache/htdocs以外de文件将不会被允许,
如果错误显示打开de话
会提示这样de错误:
Warning: open_basedir restriction in effect. File is in wrong directory in
/usr/local/apache/htdocs/open.php on line 4
等等.
4、对php相关代码进行编译
Zend对phpde贡献很大,php4de引擎就是用Zendde,而且它还开发了ZendOptimizer
和ZendEncode等许多phpde加强组件.优化器ZendOptimizer只需在
http://www.zend.com注册就可以免费得到,下面几个是用于4.0.5和4.0.6de
ZendOptimizer,文件名分别对于各自de系统:
ZendOptimizer-1[1].1.0-PHP_4.0.5-FreeBSD4.0-i386.tar.gz
ZendOptimizer-1[1].1.0-PHP_4.0.5-Linux_glibc21-i386.tar.gz
ZendOptimizer-1[1].1.0-PHP_4.0.5-Solaris-sparc.tar.gz
ZendOptimizer-1[1].1.0-PHP_4.0.5-Windows-i386.zip

优化器de安装非常方便,包里面都有详细de说明.以UNIX版本de为例,看清操
作系统,把包里deZendOptimizer.so文件解压到一个目录,假设是/usr/local/lib
下,在php.ini里加上两句:
zend_optimizer.optimization_level=15
zend_extension="/usr/local/lib/ZendOptimizer.so"
就可以了.用phpinfo()看到Zend图标左边有下面文字:
with Zend Optimizer v1.1.0, Copyright (c) 1998-2000, by Zend Technologies
那么,优化器已经挂接成功了.
但是编译器ZendEncode并不是免费de,这里提供给大家一个
http://www.PHPease.comde马勇设计de编译器外壳,如果用于商业目de,请与
http://www.zend.com联系取得许可协议.
php脚本编译后,脚本de执行速度增加不少,脚本文件只能看到一堆乱码,这将
阻止攻击者进一步分析服务器上de脚本程序,而且原先在php脚本里以明文存储
de口令也得到了保密,如mysqlde口令.不过在服务器端改脚本就比较麻烦了,
还是本地改好再上传吧.

5、文件及目录de权限设置
web目录里除了上传目录,其它de目录和文件de权限一定不能让nobody用户有写
权限.否则,攻击者可 以修改主页文件,所以web目录de权限一定要设置好
. 还有,php脚本de属主千万不能是root,因为safe_mode下读文件de函数被限
制成被读文件de属主必须 和当前执行脚本de属主是一样才能被读,否则如果
错误显示打开de话会显示诸如以下de错误:
Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not
allowed to access /etc/passwd owned by uid 0 in /usr/local/apache/htdocs/open.php
on line 3
这样我能防止许多系统文件被读,比如:/etc/passwd等.
上传目录和上传脚本de属主也要设成一样,否则会出现错误de,在safe_mode下
这些要注意.
6、mysqlde启动权限设置

mysql要注意de是不要用root来启动,最好另外建一个mysqladm用户.可以在
/etc/rc.local等系统启动脚本里加上一句:
su mysqladm -c "/usr/local/mysql/share/mysql/mysql.server start"
这样系统重启后,也会自动用mysqladmin用户启动mysql进程.
7、日志文件及上传目录de审核及
查看日志和人de惰性有很大关系,要从那么大de日志文件里查找攻击痕迹有些大海捞针,而且也未必有. web上传de目录里de文件,也应该经常检查,也许
程序有问题,用户传上了一些非法de文件,比如执行脚本等.
8、操作系统自身de补丁
一样,给系统打已知漏洞de补丁是系统管理员最基本de职责,这也是最后一道防线.

经过以上de配置,虽然说不上固若金汤,但是也在相当程度上给攻击者de测试造成很多麻烦,即使php脚本程序出现比较严重de漏洞,攻击者也无法造成实际性de破坏.如果您还有更古怪,更变态de配置方法,希望能一起分享分享;)