Posts Tagged ‘多个’

同一个页面用多个id有什么影响

星期三, 06月 4th, 2008

我知道在样式表定义一个样式de时候,可以定义id也可以定义class,例如:

ID方法:#test{color:#333333},在页面中调用内容


CLASS方法:.test{color:#333333},在页面中调用内容
id一个页面只可以使用一次,class可以多次引用.

有网友问,id和class好象没什么区别,我在页面中用了多个id在IE中显示也正常,用多个id有什么影响吗?

回答:第一影响就是不能通过W3de校验.

在页面显示上,目前de浏览器还都允许您犯这个错误,用多个相同ID“一般情况下”也能正常显示.但是当您需要用JavaScript通过id来控制这个div,那就会出现错误.

id是一个标签,用于区分不同de结构和内容,就象您de名字,如果一个屋子有2个人同名,就会出现混淆;
class是一个样式,可以套在任何结构和内容上,就象一件衣服;
概念上说就是不一样de:
id是先找到结构/内容,再给它定义样式;class是先定义好一种样式,再套给多个结构/内容.

web标准希望大家用严格de习惯来写相关代码,

例如:您可以用显示粗体,也可以用来显示,但W3C 建议大家用,因为更有语义

如果对这些细节问题不重视,觉得无所谓,
那么您就没必要向xml过渡了,也没必要学习web标准了,因为web标准应用就是从这些小细节上de改变开始,否则用现在dehtml不是也可以?

动态CSS站点教程:多个页面样式提供浏览者选择

星期三, 06月 4th, 2008

在cnbruce’’s blog上看到这个即时换STYLEde相关代码,觉得不错就COPY过来备用.
在见de例子就是:一个站点上有多个页面样式提供浏览者选择.同时,在选择了某样式后,再次打开该页面时,将仍然保持该样式.自然会想到了Cookie技术.


程序相关代码
<HTML>
<HEAD>
<link ID=”skin” rel=”stylesheet” type=”text/css”>
<TITLE>换肤技术</TITLE>
<SCRIPT LANGUAGE=javascript>
<!–
function SetCookie(name,value){
var argv=SetCookie.arguments;
var argc=SetCookie.arguments.length;
var expires=(2<argc)?argv[2]:null;
var path=(3<argc)?argv[3]:null;
var domain=(4<argc)?argv[4]:null;
var secure=(5<argc)?argv[5]:false;
document.cookie=name “=” escape(value) ((expires==null)?”":(”; expires=” expires.toGMTString())) ((path==null)?”":(”; path=” path)) ((domain==null)?”":(”; domain=” domain)) ((secure==true)?”; secure”:”");
}

function GetCookie(Name) {
var search = Name “=”;
var returnvalue = “”;
if (document.cookie.length > 0) {
offset = document.cookie.indexOf(search);
if (offset != -1) {
offset = search.length;
end = document.cookie.indexOf(”;”, offset);
if (end == -1)
end = document.cookie.length;
returnvalue=unescape(document.cookie.substring(offset,end));
}
}
return returnvalue;
}

var thisskin;
thisskin=GetCookie(”nowskin”);
if(thisskin!=”")
skin.href=thisskin;
else
skin.href=”css.css”;

function changecss(url){
if(url!=”"){
skin.href=url;
var expdate=new Date();
expdate.setTime(expdate.getTime() (24*60*60*1000*30));
//expdate=null;
//以下设置COOKIES时间为1年,自己随便设置该时间..
SetCookie(”nowskin”,url,expdate,”/”,null,false);
}
}
//–>
</SCRIPT>
</HEAD>
<BODY>

<P>请选择下面de下拉菜单测试换肤效果</P>

<a href=# onclick=”changecss(”css.css”)”>css.css</a>
<a href=# onclick=”changecss(”css1.css”)”>css1.css</a>
<a href=# onclick=”changecss(”css2.css”)”>css2.css</a>
<a href=# onclick=”changecss(”css3.css”)”>css3.css</a>
<br>

<select onchange=”changecss(this.value)”>
<option>选择样式单文件</option>
<script language=”javascript”>
var csss=new Array();
csss[0]=”css.css”;
csss[1]=”css1.css”;
csss[2]=”css2.css”;
csss[3]=”css3.css”;
var i;
for(i=0;i<4;i )
if(thisskin==csss[i])
document.write(”<option value=\”" csss[i] “\” selected>” csss[i] “样式单文件</option>”);
else
document.write(”<option value=\”" csss[i] “\”>” csss[i] “样式单文件</option>”);
</script>
</select>
</BODY>
</HTML>

ASP.NET技巧:同时对多个文件进行大量写操作对性能优化

星期二, 06月 3rd, 2008

  我自己de一个项目,需要同时对65536个文件进行多次写操作.

  如果先全部打开所有de文件,然后重复写,最后关闭所有de文件.那么第一次写操作全部完成需要16分钟左右,而第二次就需要40分钟了.没有继续测试了.

for (int i = 0; i < 65536; i )
{
fileStream[i] = new FileStream(buffDir “\\” i.ToString() “.dat”, FileMode.Create,FileAccess.Write, FileShare.Write,14000);
}
write;
write;
write;
……..
for (int i = 0; i < 65536; i )
{
fileStream[i] .close();
}

  如果在写操作de时候只打开相应de一个文件,写完关闭.那么所有写操作完成只要2分30秒左右.

  循环


for (int i=0;i<65536;i )
{
open;
write;
close;
}

  由此可见,第二种办法性能要远大于第一种.一次打开所有de文件,需要占用不小de内存,最主要de是.net在处理filestream de时候,可能要进行大量de内存分配和回收等工作,消耗了大量内存和资源.

  另外我也做个测试,如果文件数目比较小,那么第一种de性能又要大大好于第二种.

JBuilder2005单元测试之捆绑多个用例

星期一, 06月 2nd, 2008

目前我只为Subsection类生成了一个测试用例,在这节里,我按照前述de方法,通过Test Case向导为StringUtils类创建一个测试用例相关代码框架,并编写测试方法,然后将这两个测试用例捆绑组合在一个测试套件中一起运行.
  选中StringUtils类,通过File->New..->Test,双击Test Case图标为StringUtils类destring2Array()方法创建测试用例,接受默认de测试用例类名TestStringUtils.
  在向导生成de测试用例相关代码框架中,删除测试固件(因为是静态方法,没有必要用固件),即删除StringUtilsde成员变量声明,setUp()和tearDown()方法.并在类中定义一个isArrayEquals()de方法,删除向导生成detestString2Array()测试方法体中de内容,编写自己de测试相关代码,其最终相关代码如下所示:
  相关代码清单 错误!文档中没有指定样式de文字.TestStringUtils:StringUtils类de测试用例
  1. package chapter25;
  2. import junit.framework.*;
  3. public class TestStringUtils extends TestCase
  4. {
  5.  public void testString2Array() {
  6.   String str1 = null, str2 = “, str3 = “a”, str4 = “a,b,c”,str5 = “,a,b,”;
  7.   String[] arr1 = null, arr2 = {”}, arr3 = {”a”}, arr4 = {”a”, “b”, “c”},
  8.   arr5 = {”, “a”, “b”, “}, trimArr5 = {”a”, “b”};
  9.
  10.  assertNull(StringUtils.string2Array(str1, ‘,’, false));
  11.  assertTrue(isArrayEquals(arr1, StringUtils.string2Array(str1, ‘,’, false)));
  12.  assertTrue(isArrayEquals(arr2, StringUtils.string2Array(str2, ‘,’, false)));
  13.  assertTrue(isArrayEquals(arr3, StringUtils.string2Array(str3, ‘,’, false)));
  14.  assertTrue(isArrayEquals(arr4, StringUtils.string2Array(str4, ‘,’, false)));
  15.  assertTrue(isArrayEquals(arr5, StringUtils.string2Array(str5, ‘,’, false)));
  16.  assertTrue(isArrayEquals(trimArr5, StringUtils.string2Array(str5, ‘,’, true)));
  17.  assertFalse(isArrayEquals(StringUtils.string2Array(str5, ‘,’, false),
  18.  StringUtils.string2Array(str5, ‘,’, true)));
  19. }
  20.
  21. //判断两个字符数组是否相等
  22. private boolean isArrayEquals(String[] arr1, String[] arr2) {
  23.  if (arr1 == null || arr2 == null) {
  24.   if (arr1 == null && arr2 == null) {
  25.    return true;
  26.   } else {
  27.    return false;
  28.   }
  29.  } else if (arr1.length != arr2.length) {
  30.   return false;
  31.  } else {
  32.   for (int i = 0; i < arr1.length; i ) {
  33.    if (!arr1[i].equals(arr2[i])) {
  34.     return false;
  35.    }
  36.   }
  37.   return true;
  38.  }
  39. }
  40. }

  虽然JUnit框架提供了许多assertEquals()de重载方法,但却没有入参是两字符串数组deassertEquals()重载方法,所以我需要自己定义一个判断两字符串数组是否相同de方法:isArrayEquals(),如第22~39行所示.
  在testString2Array()方法中,我提供了覆盖多数情况de字符串测试点(特殊转换字符串和其目标值),如第6~8行所示.尔后调用assertXxx()设置测试规则.您也可以像上一节中deTestSubsection测试用例一样运行它.
  注意:
  如果您在内容窗格TestStringUtils文件标签上右击,发现弹出de菜单中只有Run Test using “TestSubsection”时,请在Project->Project Properties…->Run->在Run设置页中取消TestSubsection运行设置项deContext Menu选项,否则只会运行原TestSubsectionde测试用例.
  只包括10个类左右de小型项目工程也许无需用到测试套件,仅通过逐一单独运行测试用例来完成测试就可以了,但对于一个包含较多测试用例de工程,测试套件能给您带来极大de方便,它将多个测试用例捆绑在一起运行,达到一呼而百应de批量处理效果.
   下面我就来为TestSubsection和TestStringUtils这两个测试用例创建一个测试套件,并通过测试套件运行这两个测试.
  1.File->New…->Test->在Test页中双击Test Suite图标启动创建测试套件de向导,如下图所示:


  图 错误!文档中没有指定样式de文字.选择套件中捆绑de测试用例

  在对话框列表中已经列出了工程中已有de两上测试用例类,您可以通过右边deAdd…和Remove添加或删除测试用例.您可以通过Add Recursively,将指定目录下de所有测试用例一并加入.
  点击Next到下一步.
  2.指定测试套件类名.


  图 错误!文档中没有指定样式de文字.指定测试套件类名

  接受JBuilder为测试套件所提供de默认类名,按Finish完成该测试套件de创建,其相关代码如下所示:
  相关代码清单 错误!文档中没有指定样式de文字.测试套件类
  1. package chapter25;
  2. import junit.framework.*;
  3. public class TestSuite1
  4. extends TestCase
  5. {
  6.  public TestSuite1(String s) {
  7.   super(s);
  8.  }
  9.
  10. public static Test suite() {
  11.  TestSuite suite = new TestSuite();
  12.  suite.addTestSuite(chapter25.TestStringUtils.class);
  13.  suite.addTestSuite(chapter25.TestSubsection.class);
  14.  return suite;
  15. }
  16. }
  测试套件类最主要de相关代码是suite()方法(第10~15行),首先在方法中声明一个TestSuite变量,通过addTestSuite()方法将TestStringUtils和TestSubsection测试用例捆绑在一起,您也可以通过这个方法添加其他de测试用例类.
  TestSuite除可以将整个测试用例捆绑外,还可以捆绑另外de一个测试套件或一个测试用例中de测试方法:
  l 添加一个测试套件
  suite.addTest(suite_1)
  l 添加测试用例某个方法
  suite.addTest(new TestSubsection (”testGetValue”))
  在工程窗格资源树deTestSuite1文件节点上右击,在弹出de菜单中选择Run Test using Defaults,JBuilder启动JBTestRunner,运行套件中捆绑de所有测试用例,其窗口如下图所示:


  图 错误!文档中没有指定样式de文字.用测试套件运行组合运行多个测试用例

  TestSuite下有两个测试用例类,测试用例节点下是测试方法节点.

给多个地址发邮件的类

星期一, 06月 2nd, 2008

<?php
////////////////////////////////////////////////////////////
// EmailClass 0.5
// class for sending mail
//
// Paul Schreiber
// php@paulschreiber.com
// http://paulschreiber.com/
//
// parameters
// ———-
// - subject, message, senderName, senderEmail and toList are required
// - ccList, bccList and replyTo are optional
// - toList, ccList and bccList can be strings or arrays of strings
// (those strings should be valid email addresses
//
// example
// ——-
// $m = new email ( "hello there", // subject
// "how are you?", // message body
// "paul", // sender’s name
// "foo@foobar.com", // sender’s email
// array("paul@foobar.com", "foo@bar.com"), // To: recipients
// "paul@whereever.com" // Cc: recipient
// );
//
// print "mail sent, result was" . $m->send();
//
//
//
if ( ! defined( ‘MAIL_CLASS_DEFINED’ ) ) {
define(’MAIL_CLASS_DEFINED’, 1 );
class email {
// the constructor!
function email ( $subject, $message, $senderName, $senderEmail, $toList, $ccList=0, $bccList=0, $replyTo=0) {
$this->sender = $senderName . " <$senderEmail>";
$this->replyTo = $replyTo;
$this->subject = $subject;
$this->message = $message;
// set the To: recipient(s)
if ( is_array($toList) ) {
$this->to = join( $toList, "," );
} else {
$this->to = $toList;
}
// set the Cc: recipient(s)
if ( is_array($ccList) && sizeof($ccList) ) {
$this->cc = join( $ccList, "," );
} elseif ( $ccList ) {
$this->cc = $ccList;
}
// set the Bcc: recipient(s)
if ( is_array($bccList) && sizeof($bccList) ) {
$this->bcc = join( $bccList, "," );
} elseif ( $bccList ) {
$this->bcc = $bccList;
}
}
// send the message; this is actually just a wrapper for
// PHP’s mail() function; heck, it’s PHP’s mail function done right :-)
// you could override this method to:
// (a) use sendmail directly
// (b) do SMTP with sockets
function send () {
// create the headers needed by PHP’s mail() function
// sender
$this->headers = "From: " . $this->sender . "\n";
// reply-to address
if ( $this->replyTo ) {
$this->headers .= "Reply-To: " . $this->replyTo . "\n";
}
// Cc: recipient(s)
if ( $this->cc ) {
$this->headers .= "Cc: " . $this->cc . "\n";
}
// Bcc: recipient(s)
if ( $this->bcc ) {
$this->headers .= "Bcc: " . $this->bcc . "\n";
}
return mail ( $this->to, $this->subject, $this->message, $this->headers );
}
}

}
?>

PHPShop存在多个安全漏洞

星期一, 06月 2nd, 2008

  受影响系统:

  phpShop phpShop 0.6.1-b

  详细描述:

  phpShop是一款基于PHPde电子商务程序,可方便de扩展WEB功能.phpShop存在多个安全问题,远程攻击者可以利用这些漏洞攻击数据库,获得敏感信息,执行任意脚本相关代码.

  具体问题如下:

  1、SQL注入漏洞:

  当更新会话时存在一个SQL注入问题,可以对”page”变量提交恶意SQL命令而修改原有SQL逻辑,同样对”product_id”和”offset”变量进行注入也存在同样问题.

  2、用户信息泄露漏洞:

  通过查询”account/shipto”模块,可获得大量客户信息.如果用户以合法帐户登录,也可能查看管理员信息.这些信息包括客户de地址,公司名等等信息.

  3、跨站脚本执行攻击:

  多个参数对用户提交deURI参数缺少充分过滤,提交包含恶意HTML相关代码de数据,可导致触发跨站脚本攻击,可能获得目标用户de敏感信息.

  目前厂商还没有提供补丁或者升级程序.

在同一窗体中使用PHP来处理多个提交任务

星期一, 06月 2nd, 2008

在PHP中de处理窗体数据比其它网页程序语言更简单——如果您使用这种语言一段时间后,您会发现这是一个不可争辩de事实.这种操作de简易性使它可以容易地处理更为复杂de窗体事件,包括今天讨论de主题,即在同一个窗体中通过多个按钮来处理不同de任务.

为什么使用多个提交任务?
在我回答这个问题之前,先让我回答一个很显然de问题:既然许多窗体更适合单一de提交按钮,为什么有时人们需要de是两个(或者是更多)de提交按钮?

对这一问题最好de解释方法是用我最近开发项目中de一个实例来说明.在这一项目中,我de任务是给一个图书馆建立一个详细目录查询系统.书籍题目被储存在数据库中,而管理员将可以使用一个基于浏览器功能de界面来查看其中任何一本书de记录,然后对这一记录上选择执行四种操作之一:成员还书登记,成员借书登记,书本丢失记录以及书本销售记录.

以上所有任务都要通过一个独立窗体来处理,这样就需要相应de按钮来响应这些任务.传入到窗体de数据将以不同de方式处理,这取决于被点击de按钮(借书/还书和成员记录相互关联;丢失/销售记录改变详细目录表).由于一个窗体只能处理一个唯一de任务,但是相同dePHP脚本可以根据被点击de按钮和执行合适de相关代码段来处理以上四种任务.因此就需要处理多个提交任务按钮de单一窗体,以及实现不同按钮de自动响应de窗体处理相关代码段.

我首先列举一个简单例子:一个提交按扭de窗体.这样能够让您清楚地理解基本概念,并且为将要讲述de复杂例子打下铺垫.这里是一个窗体:

<html><head>Single-button form</head>
<body>

<form action=”processor.php” method=”post”> Enter a number: <input type=”text” name=”number” size=”3″> <br>
<input type=”submit” name=”submit”> </form>

</body>
</html>

以下de是调用提交任务deprocessor.php脚本:

<?php

// check for submission
// retrieve value from posted data
if ($_POST['submit'])
{
echo “You entered the number ” . $_POST['number']; }

?>

当一个窗体被提交给PHP脚本时,根据使用de提交方法(本文我假设为POST),PHP自动建立一个特定de$_POST或者$_GET数组.键入到窗体输入域内de数值会自动转化成数组中de关键数据,并可以使用常规数据符号来访问这些数据.

特别值得注意de是,如何在以上脚本中处理提交任务de按扭.当窗体被提交时,提交按钮根据自己实际de“name”转变成$_POST中de一个元素.添加以下一行相关代码就很清楚了:

print_r($_POST);

为了了解以上PHP脚本,您可以查看数组de内部结构,并可以清楚地看到不同窗体控件之间de相互联系.