2005年11月15日

<script language="javascript">
  function CheckAll(obj, oValue){
   var oBool = false;
   var oTable = document.all['oTable'];
   for (var i=1; i<oTable.rows.length; i++) {
     for (var j=0; j<oTable.rows[i].cells[0].children.length; j++) {
       oBool = (oTable.rows[i].cells[0].children[j].tagName==’INPUT’) && (oTable.rows[i].cells[0].children[j].type==’radio’) && (oTable.rows[i].cells[0].children[j].value==oValue);
       if (oBool) {
         oTable.rows[i].cells[0].children[j].checked = true;
       }
     }
   }
   for (var i=0; i<oTable.rows[0].cells[0].children.length; i++)
     oTable.rows[0].cells[0].children[i].checked = (oTable.rows[0].cells[0].children[i] == obj);
  }
</script>
<table id="oTable">
<tr>
<td> <input type="checkbox" name="a" value="1" onclick="CheckAll(this, value);"> 全优<input type="checkbox" name="a" value="2" onclick="CheckAll(this, value);"> 全良<input type="checkbox" name="a" value="3" onclick="CheckAll(this, value);">全及格 </td>
</tr>
<tr>
<td> <input type="radio" name="a" value="1"> 优<input type="radio" name="a" value="2"> 良 <input type="radio" name="a" value="3"> 及格 </td>
</tr>
<tr>
<td> <input type="radio" name="b" value="1"> 优<input type="radio" name="b" value="2"> 良 <input type="radio" name="b" value="3"> 及格 </td>
</tr>
<tr>
<td> <input type="radio" name="c" value="1"> 优<input type="radio" name="c" value="2"> 良 <input type="radio" name="c" value="3"> 及格 </td>
</tr>
<tr>
<td> <input type="radio" name="d" value="1"> 优<input type="radio" name="d" value="2"> 良 <input type="radio" name="d" value="3"> 及格 </td>
</tr>
<tr>
<td> <input type="radio" name="e" value="1"> 优<input type="radio" name="e" value="2"> 良 <input type="radio" name="e" value="3"> 及格 </td>
</tr>
<tr>
<td> <input type="radio" name="f" value="1"> 优<input type="radio" name="f" value="2"> 良 <input type="radio" name="f" value="3"> 及格 </td>
</tr>
</table> 

2005年08月24日


在经历了多支球队的争抢后,今年夏天首位被放弃的球员德里克-安德森终于找到了自己未来的方向。北京时间8月23日休斯顿消息,火箭在今天正式与安德森签订合同,尽管合约细节未被透露,但据此前的报道,安德森的合同为1+1的两年合同,合同第一年安德森只能拿到167万美元的薪金,他有权决定第二年是否继续合同。

“德里克在联盟中一直依靠他的得分著称。”火箭队经理卡罗尔-道森说:“他的投

篮、控球以及出色的传球技术都会使我们的后场更为强大,我们期望他能为球队的胜利做出贡献。”

  自从特赦条款出台后,开拓者是第一支使用这一条款的球队,他们在8月3日指定放弃了安德森,不过后者仍将得到此前合约中所涉及的2年1千8百万薪水,而开拓者也因此免去了很大一部分奢侈税。31岁的安德森是在2001年被

马刺连同斯蒂夫-史密茨一起打包送去开拓者,之后效力开拓者的四个赛季中总共打了244场比赛,平均每场贡献12分和3.3次助攻。由于伤病问题他在上赛季的最后42场比赛中仅打了8场球,严重的背伤使他的状态急剧下滑,他所参加的47场比赛中每场仅有9.2分、2.7个篮板以及3次助攻的贫乏表现。同样在2003-04赛季中安德森也缺席了多达31场比赛,不过那时他场均贡献13.6分、4.5次助攻。

  谁都无法预料加盟

火箭后的安德森会继续常挂“免战牌”还是重整旗鼓,这也是球队在签下他后所要承担的风险。但从阵容表面来看下赛季

火箭队

后的安德森会继续常挂“免战牌”还是重整旗鼓,这也是球队在签下他后所要承担的风险。但从阵容表面来看下赛季

火箭队将会十分强劲,前锋线得到斯维福特的补足后,安德森的加入另他们后卫线的得分以及组织能力都增添了不少砝码,因为他在场上可以担当控卫也可以饰演得分角色,因此麦蒂将卸下不少进攻负担,另外他丰富的经验也是这支球队所极其需要的,由此可见以接近底薪的价位签下这位球员可算是“价廉物美”,而火箭在今年的“引援”工作上也基本顺利完成。(喜欢)

<SCRIPT language=JavaScript1.2>
function html_trans(str) {
        str = str.replace(/\r/g,"");
        str = str.replace(/on(load|click|dbclick|mouseover|mousedown|mouseup)="[^"]+"/ig,"");
        str = str.replace(/<script[^>]*?>([\w\W]*?)<\/script>/ig,"");
        
        str = str.replace(/<a[^>]+href="([^"]+)"[^>]*>(.*?)<\/a>/ig,"\n[url=$1]$2[/url]\n");
        
        str = str.replace(/<font[^>]+color=([^ >]+)[^>]*>(.*?)<\/font>/ig,"\n[color=$1]$2[/color]\n");
        
        str = str.replace(/<img[^>]+src="([^"]+)"[^>]*>/ig,"\n[img]$1[/img]\n");
        
        str = str.replace(/<([\/]?)b>/ig,"[$1b]");
        str = str.replace(/<([\/]?)strong>/ig,"[$1b]");
        str = str.replace(/<([\/]?)u>/ig,"[$1u]");
        str = str.replace(/<([\/]?)i>/ig,"[$1i]");
        
        str = str.replace(/&nbsp;/g," ");
        str = str.replace(/&amp;/g,"&");
        str = str.replace(/&quot;/g,"\"");
        str = str.replace(/&lt;/g,"<");
        str = str.replace(/&gt;/g,">");
        
        str = str.replace(/<br>/ig,"\n");
        str = str.replace(/<[^>]*?>/g,"");
        str = str.replace(/\[url=([^\]]+)\]\n(\[img\]\1\[\/img\])\n\[\/url\]/g,"$2");
        str = str.replace(/\n+/g,"\n");
        
        return str;
}

function trans(){
        var str = "";
        rtf.focus();
        rtf.document.body.innerHTML = "";
        rtf.document.execCommand("paste");
        str = rtf.document.body.innerHTML;
        if(str.length == 0) {
                alert("剪切版不存在超文本数据!");
                return "";
        }
        return html_trans(str);
}
</SCRIPT>  

2005年06月21日

吊儿郎当只是你的外表!

欢迎你以后经常跟我吹

我们一起吹

管他俗不俗

相信自己OK?剩下 的大四

要珍惜每一天,因为以后你要和现有的朋友分别

学生时代就最后一个了

别再乱荒废了
好好学习OK?

2005年06月08日
今天saiy跟我提到关于php.ini 文件可以修改的问题时提到apache在windows的权限问题,最近也看到不少hacker们提到的一些获取webshell以后扩大战果的问题,但是没有看到谁注意这个服务器的权限问题,在此感谢saiy提到这个问题,如果他不说我也不会想到去查apache手册,所以我在标题前加了个转,充其量也就是个搜索而已:

PS:既然现在找到资料就把它写出来,免得以后忘记了,还有各位hacker大虾们不要骂我跟你们做对,毕竟越安全越有挑战性:)

下面来看看apache手册里面一段说明

以下为引用:

运行Apache服务的用户帐号(NT/2000)
当Apache第一次被安装为服务(例如使用-i选项),它会以用户"System"(本地系统账号)运行。 如果web服务器的所有资源都在本地系统上,这样做会问题比较少,但是将会具有很大的安全权限来影响本地机器!
本地系统账号是一个很有特权的本地账号,因此你不应该用它运行任何共享软件应用程序。 但是,它没有网络权限,不能通过任何NT安全机制离开本地机器,包括文件系统、命名管道、DCOM或secure RPC。
永远不要把网络权限授予SYSTEM账号!创建一个新的用户帐号来代替它, 给这个用户授予合适的权限,并使用"Log On As:"选项。选择开始菜单 -> 设置 -> 控制面板 -> 服务 -> apache服务 …并点击"启动服务"来访问该设置

一个运行在本地系统账号背景中的服务继承了SCM(服务控制管理器)的安全背景,与任何已登录账号都没有关联,也没有用于验证的任何证书(域名、用户名和密码)。
SYSTEM账号没有网络权限,因此对于服务一个Apache的共享安装实例或者共享页都是不可见的。如果你打算使用任何网络资源,下面的步骤应该有所帮助:

在控制面板的服务对话框中选择Apache并点击启动服务。
证实服务的账号是正确的。你可能希望为Apache服务创建一个账号。
重新输入密码和确认密码。
转到域的用户管理。
从标题栏菜单点击策略,选择用户权限。
选择高级用户权限选项。
在下拉列表中,确认以下权限已授予选择的账号:
作为操作系统一部分运行
备份文件和目录
作为服务登录
还原文件和目录
确认选择的账号是user组的成员。
确认选择的账号获得了访问所有文档和脚本目录的权力(最少需要读取和浏览访问)。
确认选择的账号对Apache日志目录有读/写/删除访问权限!
如果你允许使用这个帐号登录为一个用户,你就可以自己登录上去测试执行脚本、读取web页的权限,还可以用控制台窗口启动Apache。如果这样工作正常,你又执行了上述的操作,那么Apache就能够正常地作为服务运行了。

错误代码2186是一个很好的提示,说明你需要检查"log On As"选项,因为服务器不能访问必要的网络资源。




关于php应该注意的地方
1、很多教程(俺当年刚开始用apache的时候看到的资料几乎都这么写)都有这么一句话,把dlls目录下的所有文件copy到系统目录下,甚至有的还把extensions内的文件copy到系统目录下&@#!*$这不是完拉。(就是为了不让apache访问windows系统目录,这样不挂了)。当然也可以选择把系统目录设置为apache使用的用户可读,(那也挂了,一个opendir ~!~~~~@*^^*^$#@,想想后果)。
2、现在来看看我怎么安装php解析器。
apache 安装目录c:\program files\apache group\apache2
php 安装目录c:\php

apache设置文件里面:
以下内容为程序代码:

AddType application/x-httpd-php .php
LoadModule php4_module "C:\PHP\sapi\php4apache2.dll"




php5 设置需要改一下:)

php.ini文件复制到c:\program files\apache group\apache2目录内

php.ini的设置
以下内容为程序代码:

extension_dir = "C:\PHP\extensions"




系统环境变量:
我的电脑->反键->属性->高级->环境变量->系统变量->Path
增加一个
"C:\PHP"
前面有变量记得增加一个;

好了现在把
C:\PHP
c:\program files\apache group\apache2\php.ini
设置为apache使用的账号可读
就这样其他设置自己看着办就行了:)
2005年06月07日

  遇到发展瓶颈的步行者队假如有意出售阿泰斯特,那么火箭队该不该购进这个让人爱恨交加的“野兽”?北京时间6月6日,《火箭迷论坛报》对阿泰斯特的特点和火箭引员的动向进行了分析,结论是火箭队追逐和放弃阿泰斯特的可能性各占50%。原因很简单,因为这只野兽放到场上会吞噬对手,但在场下,他有可能误伤自己人——

  6尺7寸的阿泰斯特1999年以首轮第16顺位被芝加哥公牛队选中。加盟风之城之后,虽然在进攻方面的天赋没有被挖掘出来,但是他如影随形,宛如附骨之蛆般的防守功夫却日渐精进。在与布拉德·米勒同为交易贾伦·罗斯的附属品被交易到步行者队之后,阿泰每年都会有长足的进步。

  然而,ESPN却把阿泰称作是“篮球圈里最恐怖的男人”,所有的矛头都指向他对愤怒缺乏自控能力的弱点。无畏的人什么都不会害怕,阿泰连“天神”乔丹的肋骨都敢撞断,还有什么是他不敢做的?然而,在创造技术犯规的频率超越了“怒吼天尊”的同时,阿泰的进攻能力开始与日俱增,同时他依靠坚韧的防守功力得到了2003-04赛季的“最佳防守球员”奖项。2004-05赛季,阿泰更加一发不可收拾,场均技术统计高达24分6.4各篮板,投篮命中率达到50%。但这一切梦幻都在奥本山被一个装了半杯啤酒的纸杯打破。

  倘若火箭请来阿泰加盟,他们手中将握有一把双刃剑。就像当初的“大虫”罗德曼辅佐乔丹和皮蓬夺得三连冠一样,阿泰和姚明、麦蒂的联手,将引爆西部联盟。首先,阿泰的到来将解决火箭最大的心病——无人防守对方的最佳得分后卫和小前锋。试想,如果阿泰在阵容中,火箭首战对阵小牛的比赛中,哪轮得上斯塔克豪斯和特里猖狂?

  其次,奥本山事件之后,阿泰斯特的身价肯定会狂贬。正如1994-95赛季的“大虫”,虽然帮助马刺取得了62场常规赛胜利,平均每场抓下16.8个篮板球,但是在交易中,罗德曼只为马刺换来了威尔·普度这样的鸡肋。

  在引进阿泰的事情上,火箭完全可以冒险一试,但他们需要为次做好心理准备。因为火箭现在没有乔丹一样的人,可以震慑住这个随时可能发狂的野兽。(编辑:游悠)

2005年06月02日

表单的验证一直是网页设计者头痛的问题,表单验证类 Validator就是为解决这个问题而写的,旨在使设计者从纷繁复杂的表单验证中解放出来,把精力集中于网页的设计和功能上的改进上。

  Validator是基于javascript技术的伪静态类和对象的自定义属性,可以对网页中的表单项输入进行相应的验证,允许同一页面中同时验证多个表单,熟悉接口之后也可以对特定的表单项甚至仅仅是某个字符串进行验证。因为是伪静态类,所以在调用时不需要实例化,直接以"类名+.语法+属性或方法名"来调用。此外,Validator还提供3种不同的错误提示模式,以满足不同的需要。

  完整文档下载: Validator.chm (zip压缩,111K)

  Validator目前可实现的验证类型有:

  1.是否为空;
  2.中文字符;
  3.双字节字符
  4.英文;
  5.数字;
  6.整数;
  7.实数;
  8.Email地址;
  9.使用HTTP协议的网址;
  10.电话号码;
  11.货币;
  12.手机号码;
  13.邮政编码;
  14.身份证号码;
  15.QQ号码;
  16.日期;
  17.符合安全规则的密码;
  18.某项的重复值;
  19.两数的关系比较;
  20.判断输入值是否在(n, m)区间;
  21.输入字符长度限制(可按字节比较);
  22.对于具有相同名称的单选按钮的选中判断;
  23.限制具有相同名称的多选按钮的选中数目;
  24.自定义的正则表达式验证;

  运行环境(客户端):

  在Windows Server 2003下用IE6.0+SP1和Mozilla Firefox 1.0测试通过;
  在Lunix RedHat 9下的Netscape测试通过;


 <title>表单验证类 Validator v1.0</title>
 <style>
 body,td{font:normal 12px Verdana;color:#333333}
 input,textarea,select,td{font:normal 12px Verdana;color:#333333;border:1px solid #999999;background:#ffffff}
 table{border-collapse:collapse;}
 td{padding:3px}
 input{height:20;}
 textarea{width:80%;height:50px;overflow:auto;}
 form{display:inline}
 </style>
 <table align="center">
  <form name="theForm" id="demo" action="" method="get" onSubmit="return Validator.Validate(this,2)">
    <tr>
   <td>真实姓名:</td><td><input name="Name" dataType="Chinese" msg="真实姓名只允许中文"></td>
  </tr>
  <tr>
   <td>英文名:</td><td><input name="Nick" dataType="English" require="false" msg="英文名只允许英文字母"></td>
  </tr>
    <tr>
   <td>主页:</td><td><input name="Homepage" require="false" dataType="Url"   msg="非法的Url"></td>
  </tr>
  <tr>
   <td>密码:</td><td><input name="Password" dataType="SafeString"   msg="密码不符合安全规则" type="password"></td>
  </tr>
  <tr>
   <td>重复:</td><td><input name="Repeat" dataType="Repeat" to="Password" msg="两次输入的密码不一致" type="password"></td>
  </tr>
  <tr>
   <td>信箱:</td><td><input name="Email" dataType="Email" msg="信箱格式不正确"></td>
  </tr>
    <tr>
   <td>信箱:</td><td><input name="Email" dataType="Repeat" to="Email" msg="两次输入的信箱不一致"></td>
  </tr>
  <tr>
   <td>QQ:</td><td><input name="QQ" require="false" dataType="QQ" msg="QQ号码不存在"></td>
  </tr>
    <tr>
   <td>身份证:</td><td><input name="Card" dataType="IdCard" msg="身份证号码不正确"></td>
  </tr>
  <tr>
   <td>年龄:</td><td><input name="Year" dataType="Range" msg="年龄必须在18~28之间" min="18" max="28"></td>
  </tr>
   <tr>
   <td>年龄1:</td><td><input name="Year1" require="false" dataType="Compare" msg="年龄必须在18以上" to="18" operator="GreaterThanEqual"></td>
  </tr>
   <tr>
   <td>电话:</td><td><input name="Phone" require="false" dataType="Phone" msg="电话号码不正确"></td>
  </tr>
   <tr>
   <td>手机:</td><td><input name="Mobile" require="false" dataType="Mobile" msg="手机号码不正确"></td>
  </tr>
     <tr>
   <td>生日:</td><td><input name="Birthday" dataType="Date" format="ymd" msg="生日日期不存在"></td>
  </tr>
   <tr>
   <td>邮政编码:</td><td><input name="Zip" dataType="Custom" regexp="^[1-9]\d{5}$" msg="邮政编码不存在"></td>
  </tr>
  <tr>
   <td>邮政编码:</td><td><input name="Zip1" dataType="Zip" msg="邮政编码不存在"></td>
  </tr>
  <tr>
   <td>操作系统:</td><td><select name="Operation" dataType="Require"  msg="未选择所用操作系统" ><option value="">选择您所用的操作系统</option><option value="Win98">Win98</option><option value="Win2k">Win2k</option><option value="WinXP">WinXP</option></select></td>
  </tr>
  <tr>
   <td>所在省份:</td><td>广东<input name="Province" value="1" type="radio">陕西<input name="Province" value="2" type="radio">浙江<input name="Province" value="3" type="radio">江西<input name="Province" value="4" type="radio" dataType="Group"  msg="必须选定一个省份" ></td>
  </tr>
  <tr>
   <td>爱好:</td><td>运动<input name="Favorite" value="1" type="checkbox">上网<input name="Favorite" value="2" type="checkbox">听音乐<input name="Favorite" value="3" type="checkbox">看书<input name="Favorite" value="4" type="checkbox"" dataType="Group" min="2" max="3"  msg="必须选择2~3种爱好"></td>
  </tr>
   <td>自我介绍:</td><td><textarea name="Description" dataType="Limit" max="10"  msg="自我介绍内容必须在10个字之内">中文是一个字</textarea></td>
  </tr>
     <td>自传:</td><td><textarea name="History" dataType="LimitB" min="3" max="10"  msg="自传内容必须在[3,10]个字节之内">中文是两个字节t</textarea></td>
  </tr>
  <tr>
   <td colspan="2"><input name="Submit" type="submit" value="确定提交"><input onClick="Validator.Validate(document.getElementById(‘demo’))" value="检验模式1" type="button"><input onClick="Validator.Validate(document.getElementById(‘demo’),2)" value="检验模式2" type="button"><input onClick="Validator.Validate(document.getElementById(‘demo’),3)" value="检验模式3" type="button"></td>
  </tr>
  </form>
 </table>
 <script>
 /*************************************************
 Validator v1.0
 cody by 我佛山人
 wfsr@cunite.com
 http://www.cunite.com
*************************************************/
 Validator = {
 Require : /.+/,
 Email : /^\w+([-+.]\w+)*@\w+([-.]\\w+)*\.\w+([-.]\w+)*$/,
 Phone : /^((\(\d{3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}$/,
 Mobile : /^((\(\d{3}\))|(\d{3}\-))?13\d{9}$/,
 Url : /^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\’:+!]*([^<>\"\"])*$/,
 IdCard : /^\d{15}(\d{2}[A-Za-z0-9])?$/,
 Currency : /^\d+(\.\d+)?$/,
 Number : /^\d+$/,
 Zip : /^[1-9]\d{5}$/,
 QQ : /^[1-9]\d{4,8}$/,
 Integer : /^[-\+]?\d+$/,
 Double : /^[-\+]?\d+(\.\d+)?$/,
 English : /^[A-Za-z]+$/,
 Chinese :  /^[\u0391-\uFFE5]+$/,
 UnSafe : /^(([A-Z]*|[a-z]*|\d*|[-_\~!@#\$%\^&\*\.\(\)\[\]\{\}<>\?\\\/\’\"]*)|.{0,5})$|\s/,
 IsSafe : function(str){return !this.UnSafe.test(str);},
 SafeString : "this.IsSafe(value)",
 Limit : "this.limit(value.length,getAttribute(‘min’),  getAttribute(‘max’))",
 LimitB : "this.limit(this.LenB(value), getAttribute(‘min’), getAttribute(‘max’))",
 Date : "this.IsDate(value, getAttribute(‘min’), getAttribute(‘format’))",
 Repeat : "value == document.getElementsByName(getAttribute(‘to’))[0].value",
 Range : "getAttribute(‘min’) < value && value < getAttribute(‘max’)",
 Compare : "this.compare(value,getAttribute(‘operator’),getAttribute(‘to’))",
 Custom : "this.Exec(value, getAttribute(‘regexp’))",
 Group : "this.MustChecked(getAttribute(‘name’), getAttribute(‘min’), getAttribute(‘max’))",
 ErrorItem : [document.forms[0]],
 ErrorMessage : ["以下原因导致提交失败:\t\t\t\t"],
 Validate : function(theForm, mode){
  var obj = theForm || event.srcElement;
  var count = obj.elements.length;
  this.ErrorMessage.length = 1;
  this.ErrorItem.length = 1;
  this.ErrorItem[0] = obj;
  for(var i=0;i<count;i++){
   with(obj.elements[i]){
    var _dataType = getAttribute("dataType");
    if(typeof(_dataType) == "object" || typeof(this[_dataType]) == "undefined")  continue;
    this.ClearState(obj.elements[i]);
    if(getAttribute("require") == "false" && value == "") continue;
    switch(_dataType){
     case "Date" :
     case "Repeat" :
     case "Range" :
     case "Compare" :
     case "Custom" :
     case "Group" :
     case "Limit" :
     case "LimitB" :
     case "SafeString" :
      if(!eval(this[_dataType])) {
       this.AddError(i, getAttribute("msg"));
      }
      break;
     default :
      if(!this[_dataType].test(value)){
       this.AddError(i, getAttribute("msg"));
      }
      break;
    }
   }
  }
  if(this.ErrorMessage.length > 1){
   mode = mode || 1;
   var errCount = this.ErrorItem.length;
   switch(mode){
   case 2 :
    for(var i=1;i<errCount;i++)
     this.ErrorItem[i].style.color = "red";
   case 1 :
    alert(this.ErrorMessage.join("\n"));
    this.ErrorItem[1].focus();
    break;
   case 3 :
    for(var i=1;i<errCount;i++){
    try{
     var span = document.createElement("SPAN");
     span.id = "__ErrorMessagePanel";
     span.style.color = "red";
     this.ErrorItem[i].parentNode.appendChild(span);
     span.innerHTML = this.ErrorMessage[i].replace(/\d+:/,"*");
     }
     catch(e){alert(e.description);}
    }
    this.ErrorItem[1].focus();
    break;
   default :
    alert(this.ErrorMessage.join("\n"));
    break;
   }
   return false;
  }
  return true;
 },
 limit : function(len,min, max){
  min = min || 0;
  max = max || Number.MAX_VALUE;
  return min <= len && len <= max;
 },
 LenB : function(str){
  return str.replace(/[^\x00-\xff]/g,"**").length;
 },
 ClearState : function(elem){
  with(elem){
   if(style.color == "red")
    style.color = "";
   var lastNode = parentNode.childNodes[parentNode.childNodes.length-1];
   if(lastNode.id == "__ErrorMessagePanel")
    parentNode.removeChild(lastNode);
  }
 },
 AddError : function(index, str){
  this.ErrorItem[this.ErrorItem.length] = this.ErrorItem[0].elements[index];
  this.ErrorMessage[this.ErrorMessage.length] = this.ErrorMessage.length + ":" + str;
 },
 Exec : function(op, reg){
  return new RegExp(reg,"g").test(op);
 },
 compare : function(op1,operator,op2){
  switch (operator) {
   case "NotEqual":
    return (op1 != op2);
   case "GreaterThan":
    return (op1 > op2);
   case "GreaterThanEqual":
    return (op1 >= op2);
   case "LessThan":
    return (op1 < op2);
   case "LessThanEqual":
    return (op1 <= op2);
   default:
    return (op1 == op2);           
  }
 },
 MustChecked : function(name, min, max){
  var groups = document.getElementsByName(name);
  var hasChecked = 0;
  min = min || 1;
  max = max || groups.length;
  for(var i=groups.length-1;i>=0;i–)
   if(groups[i].checked) hasChecked++;
  return min <= hasChecked && hasChecked <= max;
 },
 IsDate : function(op, formatString){
  formatString = formatString || "ymd";
  var m, year, month, day;
  switch(formatString){
   case "ymd" :
    m = op.match(new RegExp("^\\s*((\\d{4})|(\\d{2}))([-./])(\\d{1,2})\\4(\\d{1,2})\\s*$"));
    if(m == null ) return false;
    day = m[6];
    month = m[5]–;
    year =  (m[2].length == 4) ? m[2] : GetFullYear(parseInt(m[3], 10));
    break;
   case "dmy" :
    m = op.match(new RegExp("^\\s*(\\d{1,2})([-./])(\\d{1,2})\\2((\\d{4})|(\\d{2}))\\s*$"));
    if(m == null ) return false;
    day = m[1];
    month = m[3]–;
    year = (m[5].length == 4) ? m[5] : GetFullYear(parseInt(m[6], 10));
    break;
   default :
    break;
  }
  var date = new Date(year, month, day);
        return (typeof(date) == "object" && year == date.getFullYear() && month == date.getMonth() && day == date.getDate());
  function GetFullYear(y){return ((y<30 ? "20" : "19") + y)|0;}
 }
 }
 </script>

by soola


使用PHP编程的最大好处是学习这种编程语言非常容易以及其丰富的库。即使对需要使用的函数不是十分了解,我们也能够猜测出如何完成一个特定的任务。

尽管PHP非常简单易学,但我们仍然需要花费一点时间来学习PHP的一些编程技巧,尤其是与性能和内存占用相关的技巧。在PHP中,有许多小技巧能够使我们减少内存的占用,并提高应用程序的性能。在本篇文章中,我们将对PHP应用程序的分析、如何改变脚本代码以及比较优化前后的各种参数值进行简要的介绍


通过在程序中设置计时的程序,并反复执行这些代码,我们可以获得有关程序执行速度的一组数据,这些数据可以可以用来发现程序中的瓶颈,以及如何进行优化,提高应用程序的性能。

也许读者曾经听说过PEAR库吧。我们将使用PEAR库创建在分析时需要使用的例子,这也是对现有的代码进行分析的最简单的方法,它使我们无需使用商用产品就能对代码进行分析。

我们要使用的库的名字是PEAR::Benchmark,它对于对代码进行分析和性能测试非常有用。这个库提供一个名字为Benchmark_Timer()的类,能够记录一个函数调用和下一个函数调用之间的时间。在对代码的性能进行测试时,我们可以得到一个详细的脚本执行结果,它非常简单,如下所示:


<?php

include_once("Benchmark/Timer.php");

  $bench = new Benchmark_Timer; $bench->start();

  $bench->setMarker(‘Start of the script’); 现在处于睡眠状态几分钟

  sleep(5); $bench->stop(); // 从计时器中获得分析信息

  print_r($bench->getProfiling());

?>

上面代码执行后的输出如下所示:

Array

  (

  [0] => Array

  (

  [name] => Start

  [time] => 1013214253.05751200

  [diff] => -

  [total] => 0

  )

[1] => Array

  (

  [name] => Start of the script

  [time] => 1013214253.05761100

  [diff] => 9.8943710327148E-05

  [total] => 9.8943710327148E-05

  )

[2] => Array

  (

  [name] => Stop

  [time] => 1013214258.04920700

  [diff] => 4.9915959835052

  [total] => 4.9916949272156

  )

  )

上面的数字似乎是一组杂乱无章的数字,但如果程序的规模更大,这些数字就十分地有用了。

也许广大读者也能猜测到,数组的第一个表目是实际调用Benchmark_Timer()类的方法,例如

$bench->start()、$bench->setMarker()和$bench->stop(),与这些表目有关的数字是相当简单的,现在我们来仔细地研究这些数字:

[0] => Array

  (

  [name] => Start

  [time] => 1013214253.05751200

  [diff] => -

  [total] => 0

  )

time表目指的是何时对Benchmark_Timer()的start()方法调用的UNIX的timestamp,diff表目表示这次调用和上次调用之间的时间间隔,由于这里没有上一次,因此显示出了一个破折号,total表目指的是自测试开始到这一特定的调用之前代码运行的总的时间。下面我们来看看下一个数组的输出:

[1] => Array

  (

  [name] => Start of the script

  [time] => 1013214253.05761100

  [diff] => 9.8943710327148E-05

  [total] => 9.8943710327148E-05

  )

从上面的数字我们可以看出,在调用$bench->start()之后,程序运行了9.8943710327148E-05秒(也就是

0.0000989秒)后开始调用$bench->setMarker(….)。

一次真实的性能测试经历

尽管上面的例子不错,但在对于决定如何优化你的站点代码设计方面,它真的不能算是一个好例子。下面我将用我自己作为网站技术人员的一段亲身经历来说明如何解决性能方面存在的问题。

我并不大理解网站使用的代码,因为它是根据特殊的需求,历经多年开发而成的━━其中的一个模块包括网站转换代码,另一个模块记录网站的使用情况,其他的模块也各有各的作用。我和网站的主要开发者都意识到网站的代码需要优化,但又不清楚问题出在哪儿。

为了尽快地完成任务,我开始研究网站的主要脚本代码,并在全部脚本代码以及其包含文件中添加了一些$bench->setMarker()命令,然后分析$bench->getProfiling()的输出,并对得到的结果大吃一惊,原来问题出在一个与获得特定语言名字(例如en代表english)的转换代码的函数调用中,该函数在每个页面上都会被使用数百次。每次调用该函数时,脚本代码都会对一个MySQL数据库进行查询,从一个数据库表中获得真正的语言名字。

于是我们这一类的信息创建了一个缓冲系统。经过短短2天时间的工作,我们使系统的性能得到了很大的提高,第一周内页面的浏览量也因此而增加了40%。当然了,这只是一个有关分析代码能够提高互联网应用或互联网网站性能的例子。

性能测试函数调用

在分析一个脚本或网页(以及其包含文件)时,尽管Benchmark_Timer()特别有用,但它并不科学,因为要获得分析的数据我们必须多次加载脚本,而且它也不是针对某个类或函数调用的。

PEAR::Benchmark库中的另一个被称作Benchmark_Iterator的类能够很好地解决这一个问题,它能够针对特定的函数或类的方法,显示其分析信息。它的用途是能够能够从测试中获得一致的结果,因为我们知道,如果运行一段脚本一次,其运行时间为10秒,并不意味着它每次的运行时间总是10秒。

In any case, let’s see some examples:

// 连接数据库的代码

  include_once("DB.php");

  $dsn = array(

  ’phptype’ => ‘mysql’,

  ’hostspec’ => ‘localhost’,

  ’database’ => ‘database_name’,

  ’username’ => ‘user_name’,

  ’password’ => ‘password’

  );

  $dbh = DB::connect($dsn); function getCreatedDate($id)

  {

  global $dbh; >$stmt = "SELECT created_date FROM users WHERE id=$id";

  // 在这里使用PEAR::DB

  $created_date = $dbh->getOne($stmt);

  if ((PEAR::isError($created_date)) ||

  (empty($created_date))) {

  return false;

  } else {

  return $created_date;

  }

  }include_once ‘Benchmark/Iterate.php’;

  $bench = new Benchmark_Iterate; // 运行getDate函数10次

  $bench->run(10, ‘getCreatedDate’, 1);// 打印分析信息

  print_r($bench->get());

  ?>

运行上面的代码能够产生与下面相似的结果:

Array

  (

  [1] => 0.055413007736206

  [2] => 0.0012860298156738

  [3] => 0.0010279417037964

  [4] => 0.00093603134155273

  [5] => 0.00094103813171387

  [6] => 0.00092899799346924

  [7] => 0.0010659694671631

  [8] => 0.00096404552459717

  [9] => 0.0010690689086914

  [10] => 0.00093603134155273

  [mean] => 0.0064568161964417

  [iterations] => 10

  )

上面的这些数字很好理解,mean条目表示getCreatedDate()函数10次运行的平均时间。在进行实际测试时,应该至少运行1000次,但这个例子得出的结果已经足够说明问题了。

结束语

希望广大读者能够通过本篇文章掌握如何迅速地对PHP代码进行分析的基本方法。在这里我还还要提醒广大读者的是,对代码进行分析不是一件简单的事儿,因为我们必须掌握大量的有关该种语言的特性。在代码中添加计时用的代码有助于找出运行速度缓慢的函数,利用多次重复的方法使我们能够发现对代码进行正确优化的方法。

<?
/*
 *  作者:心灯
 *  功能:实现从指定时间向下推N个月的函数
 *  month($ymd,$len) $ymd时间,$len推出几个月
 *  $ymd=’2005-01-01′;
 */
function month($ymd=”,$len=’12′){
    $month  = array();
    $lang   = $lang."<meta http-equiv=\"Content-Type\" content=\"text/html; charset=gb2312\">";
    if($ymd){//判断时间格式是否正确
        if(!ereg("([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})",$ymd)){           
            echo "<script>alert(‘函数参数中的日期格式不对’);history.back()</script>";
            exit;
        }
    }
    if($len){
        if(!ereg("[0-9]+",$len)){           
            echo $lang."<script>alert(‘函数中的时间长度中含有非法字段’);history.back()</script>";
            exit;
        }
    }
    for($i=0;$i<$len;$i++){
        if($i==0){
            $mktime = $ymd?strtotime($ymd):time();
        }
        $month[] = date("Y-m",$mktime);//可以根据需要来设计置你要的格式
        $day = date("t",$mktime);
        if($i==0)
            $reday = date("d",$mktime);
        else
            $reday = $day;
        $t1   = $mktime;
        $mktime=date("Y-m-d",mktime(date("H",$t1),date("i",$t1),date("s",$t1),date("m",$t1),date("d",$t1)-$reday,date("Y",$t1)));
        $mktime =strtotime($mktime);       
    }
    return $month;
}
$month = month(”, 3);
foreach($month as $key => $v){
    echo $v."<br>";
}
?>

2005年05月26日

海!出发!

游戏策划:番茄游戏开发策划有限划股份没钱抽风公司.

游戏起源.

发生在动荡的年代,西班牙,葡萄牙,以及英国由于日耳曼帝国的阻挠,失去了于东方古国(中国)贸易的唯一路上途径,于是一群怀着梦想和承担着祖国期望的青年被派遣出海寻找贸易的路线,随后麦哲伦发现了好望角,哥伦布发现了新大陆.通往东方古国的大门撤离打开了.而也就如此同时一些过于渴望财富的人,为了获得更多的金钱更多的财富.而拿起了非法的武器成为了海盗,要么成为了人口贩.

或许是上帝觉得人类过于贪婪,随着黑死病的席卷而去.成千上万的人失去了生命,于是人们开始畏惧大海,开始害怕大海除了带来财富外还会带来灾难.

就这样,延续了百年的航海线断开了.

几十年的时光,人们渐渐的淡忘了黑死病所带来的死亡和恐惧,于是西班牙国王以及葡萄牙的国王坐到了一起,共同讨论再次把断开的航海线连接的事宜..

"去寻找你们的未来吧,年轻人.海以外的一切都是你们的."两位国王在港口为青年航海家送行的时候握着手这样说.

于是无数的青年又象自己的祖辈一样,蹬上了自己的战舰和商船,在国王的注视下,离开了港口.

航海世纪的第二次黎明———哥伦布日.

游戏概要:本游戏主要面对的是15到45岁的玩家,基本操作界面为XP.需要配置最低为256内存.P41.8
CPU游戏为3D图形模式.主要讲述了第二次航海世纪的所发生的事情.其中包括了爱情,友情和亲情..主要以海战和发展船型为主要游戏性,其次游戏本身鼓励玩家创造海战和贸易的工具.比如炮,锚,以及桅杆船造型等等.

本游戏分为9大阵营:

第一阵营,日尔曼阵营,如果玩家想从陆地穿越去东方古国必须经过的就是日尔曼帝国.阵营情况,全部敌对.

第二阵营,西班牙,葡萄牙为首的联合阵营.也就是第二黎明发起的国家.怀着对东方的憧憬和美好未来的期待.阵营情况,对(中国)亲密.对英国(敌对)

第三阵营,英国,作为海上贸易的竞争国,英国不允许其他的国家获得高额的利润和财富,于是英国作为唯一没有受到黑死病波及的国家,依靠着本身强大的海军势力,对所有经过他们视线的别国舰队都会点燃加农炮的引信.阵营情况(荷兰西班牙葡萄牙)敌对.对(中国)友好.

第四阵营,东方古国(中国)同样有着无数的青年憧憬海外的世界,匈奴还在关外游弋,而且美丽高耸的西玛拉亚山又那么高不可攀.于是很多人也蹬上了船,为追寻自己的梦想而出海.对(日本)敌对,其他友好.对(英国)中立.

第五阵营,日本(扶桑)由于德川幕府的闭关锁国的政策,日本对于海外的一切都充满着畏惧.一直到荷兰人用大炮打开了日本禁锢的大门,才使得许多的年轻人看到了不一样的世界.而与此同时,充满野心的德川家发觉在自己的眼皮底下竟然有一个充满资源,地域辽阔的肥肉(中国)于是日本就象海盗一样开始袭击中国的港口,村落,从其中掠夺着大量的金银珠宝,不过人们只看到了表面,此时的德川家已经不满足于掠夺一样的快感,而更希望一口吞下中国这块肥肉。阵营情况(对中国)敌对,(西班牙荷兰,.葡萄牙,英国)中立.

第六阵营.非洲土著.他们站在岸边,膜拜着海上的大船,在他们眼里那不单单只是船,好象是神所创造的奇迹.而与此同时奇迹也带来了噩梦,无数的白人冲上了非洲大陆,掠夺走了无数的青年壮年,.于是他们又仇视那些大船,对于他们而言,大船是梦想的开始,也是恐惧的起点.阵营(对英国葡萄牙西班牙荷兰)敌对.对(中国)友好.

第七阵营 海盗.他们原本也是对大海充满着期待和渴望的青年,可是对金钱和财富的直着却蒙蔽了他们的双眼,他们叫嚣着挥舞着武器,抢夺来往的船只,在他们眼里没有国家,没有地位.只有金币落下的声音.全部敌对.不过还是有些海盗与众不同,他们期待的更多的是刺激的生活,寻宝的乐趣,对于他们而言,面对着商船和军舰,他们更喜欢与军舰拼杀.他们总是说着自己的信条,,即使死去,也不无为的老死.对各国军舰敌对,对商船无害.

第八阵营,海王.就好象大陆上每个国家都有领主一样,4大洋也都有各自的王所管辖,他们有的是海盗出身,也有海军出身,如果你不经意冒犯了他们的军队和所保护的商船,那么换来的可能是穿行大洋时遭受的难以预计的袭击….所以如果你想从事海盗,或者想在他管辖的海域袭击敌国的船舰的时候,最少要获得他的掠夺许可证,或者打败他强大的海军.否则,还是不要随便乱开炮的好.阵营全部中立.


第九阵营,海妖  不要漠视神话的存在,所谓艺术来源于生活高于生活,所以当你开船出海的时候,不要以为自己行进在果动一样纯洁透明的液体上,不要忘记水中那无数饥饿的海兽,尤其是各种海妖.对于他们而言,无论你多么雄心装志都是不过是一顿美餐而已.阵营全部敌对.(威胁很大)


介绍完阵营该介绍人类的出生地了.分为,英国,.葡萄牙,西班牙,荷兰,中国,日本,.以及南非.

首先英国,出生地环境幽雅,而且出发时所遇到的阻挠最低.由于有强大的海军.贸易线路顺畅,适合初级玩家.不过由于地理位置制约了游戏科技的发展,发展比较缓慢.

其次是葡萄牙和西班牙.两个国家差异基本不大,不过如果以西班牙出海的人要小心英国在英吉利海峡游弋的舰队…两个国家都比较适合初级玩家游戏,不过需要小心非本国的舰队,以免遭到伏击,在葡萄牙出海的玩家要注意,附近的水流,当春天和秋天来临的时候海潮会把船向西南方向推,如果风向不合适的话,很容易被水流推离大陆,从而遭到深海海妖的袭击,也有可能遇到海盗…由于遭受过黑死病的袭击,所以这两个国家的经济发展都很迟缓,不过科技发展由于受到德国,以及日耳曼文化的影响所以发展比较迅速.

而后是荷兰.这个国家的所有港口在英国海军的覆盖范围,所以出海要快,尽量不要逆风航行,荷兰风景优美,气候微寒.不过这恰恰培养了荷兰人坚强耐吃苦的性格.荷兰的船是他的优势,船宽扳厚,前有铁头,适合破冰前进.而且宽大的舱体很适合储藏跟多的食物.所以荷兰人可以顺着北极圈绕过所有海盗和其他国家的贪婪者.不过却很容易遇到海妖,而且冬季后无法穿越,所以荷兰适合高级玩家操作,荷兰科技发达,经济状况适中.唯一缺点就是舰船装甲薄,吃水深.

再者是东方古国(中国)拥有强大的海军和很高超的科技,建造的船坚固而且宽敞,不过恰恰是好处太多,使得中国的官吏不重视科技的发展,科技发展后期会很缓慢,而且用于发展的资金会很少,所以船看起来都很粗糙.航行速度慢造价高昂.而且所收取的航行费是其他地方的数倍.所以不太合适新手的接触.而且如果驾驶低级穿出海贸易的时候,还得小心日本军舰的袭击和日本海盗的抢夺.经济高,科技高,船造价高,税高.是中国的特点.后期需要国人自己的资助才有可能与其他国家的科技持平.


然后是日本(扶桑)从荷兰敲开日本锁国的大门后.日本航海业的发展突飞猛进.不过突飞猛进造成了日本经济下滑和资源匮乏.所以他把目标对准了中国,希望从中国身上获得好处.日本的船航行速度快,吃水浅,造价低廉,.而且只收很低的出海费以及维修费.而且日本初期国家会为舰队配备火炮.一船1门.所以初期日本水手就可以经营海盗模式,不过到后期,日本经济发展的限制,武器的性能一直不是很好,可是低廉的价格弥补了一切.而且日本制造的船可以比其他国家多1到两个炮眼.射击速度快.

最后是非洲人,南非人,他们仇恨白人的所作所为,于是也尝试着靠航海来改变自己国家的命运,由于南非是被掠夺国,所以资源匮乏,舰船的装甲很薄,航行速度一般,.不过依靠着非洲人的毅力和百折不挠的性格,非洲的舰队还是开始出海贸易来获得自身改变所需要的资源.非洲人精通草药和动物学.所以海妖对非洲航海家的威胁较小.非洲的舰船没有炮口,他们不太喜欢战争所带来的后果,所以他们只希望获得更多的资源.不过处于好望角.是海盗,各航海家,海妖出没的地方,所以航行贸易都十分危险.只适合高级玩家(喜好贸易的玩家作为出生点)


以势力而论.
中国,>英国>荷兰>日本>西班牙或葡萄牙>南非.
以航海术论
西班牙或葡萄牙>英国>荷兰>中国>日本>南非
以资源论
中国>南非>英国>葡萄牙或西班牙>荷兰>日本

以科技发展水平看
中国>荷兰>英国>葡萄牙或西班牙>日本>南非

以科技发展速度看

日本>英国>荷兰>葡萄牙或西班牙>南非>中国

以战舰威力看

英国>日本>荷兰>葡萄牙或者西班牙>中国>南非.

以火炮使用看
日本>英国>荷兰>中国>西班牙或者葡萄牙>南非

以贸易成本看

中国>葡萄牙西班牙>荷兰>英国>日本>南非

以舰队的耐久看

荷兰>英国>日本>葡萄牙西班牙>中国>南非

以舰队的航行能力看

荷兰>中国>英国>葡萄牙和西班牙>日本>南非

以上是国家基本的内容,整体势力平均.

所谓DIY船,就是给处一个船的基本模型,你可以通过更换装甲,船首象,以及穿帆的样子,颜色,图案,成分的不同而改变船的基本造型和能力.

而后是四季节对游戏的造成的影响,影响显著的就是风的大小,风力的方向,基本春天的风比较大,其次是秋天,然后才是夏天和冬天.

船的物资,除了携带的商品外,船还一定要携带食物,水和水果….当城市和港口的累积的贸易值达到一定程度后还会出现压缩饼干,以及水果罐头(注:水果是方式坏血病的物品,当船离开港口如果游戏时间4个月没有靠岸或者没有水果的情况下,船员会患病直到死亡.)

船的武器,以及游戏的性能,和游戏人物的介绍将由下一篇再次介绍,现在太晚了,先写到这里,这个是环境策划的基本稿..(未修改)