分类: 网页设计

  • 搜索引擎排序技术

    随着“眼球经济”席卷互联网,成千上万的资金迅速流向最能吸引浏览着眼球的搜索引擎市场。有大量调查显示搜索引擎市场正处在高速发展时期,成为了未来几年内最具发展潜力的产业之一。随着Google、百度、中国搜索等各具特色的搜索引擎逐渐成为人们最常用的网络工具,企业对搜索引擎的注意力也从“观察”升级为“动武”。

    随着市场容量和使用者人数的不断激增,如何完善搜索功能使之更加公平、公开、标准和人性化也就随之成为了一个备受关注的话题。但是有一个矛盾体在这其中不断的显现出来:收费可以为搜索引擎公司带来利润,但同时会降低访问者的体验满意度。如何权衡金钱和用户需求之间的天平呢?

    Google成功的秘密

    到2004年为止,Google 已经连续两年被评为全球第一品牌,Google成立仅五年时间,最初只是两个斯坦福大学学生的研究项目。这不能不说是一个奇迹,就像比尔?盖茨创制奇迹一样。比尔?盖茨能创造奇迹,是因为他看准了个人计算机软件市场的趋势,所以创建的公司叫Microsoft(微软):Micro(小)Soft(软件)。 那么Google呢?在Google出来之前已经有一些很有成就的搜索引擎公司,其实力也很强,看来不只是Google看见了搜索的趋势.Google究竟成功的秘密在哪儿?

    Google的成功有许多因素,最重要的是Google对搜索结果的排序比其它搜索引擎都要好.Google保证让绝大部分用搜索的人,都能在搜索结果的第一页找到他想要的结果。客户得到了满足,下一次还过来,而且会向其他人介绍,这一来一往,使用的人就多了。所以Google在没有做任何广告的前提下,让自己成为了全球最大的品牌.Google究竟采用了哪种排序技术?PageRank,即网页级别。

    Google有一个创始人叫Larry Page,据说PageRank的专利是他申请的,于是依据他的名字就有了Page Rank.国内也有一家很成功的搜索引擎公司,叫百度。百度的创始人李彦宏说,早在1996年他就申请了名为超链分析的专利,PageRank的原理和超链分析的原理是一样的,而且PageRank目前还在Paten-pending(专利申请中)。言下之意是这里面存在专利所有权的问题。这里不讨论专利所有权,只是从中可看出,成功搜索引擎的排序技术,就其原理上来说都差不多,那就是链接分析。超链分析和PageRank都属于链接分析。

    链接分析到底为何物?由于李彦宏的超链分析没有具体的介绍,笔者唯一看过的就是在美国专利局网站上关于李彦宏的专利介绍.PageRank的介绍倒是不少,而且目前Google毕竟是全球最大的搜索引擎,这里以PageRank为代表,详细介绍链接分析的原理。

    PageRank揭密

    PageRank的原理类似于科技论文中的引用机制:谁的论文被引用次数多,谁就是权威。说的更白话一点:张三在谈话中提到了张曼玉,李四在谈话中也提到张曼玉,王五在谈话中还提到张曼玉,这就说明张曼玉一定是很有名的人。在互联网上,链接就相当于“引用”,在B网页中链接了A,相当于B在谈话时提到了A,如果在C、D、E、F中都链接了A,那么说明A网页是最重要的,A网页的PageRank值也就最高。

    如何计算PageRank值有一个简单的公式:

    其中:系数为一个大于0,小于1的数。一般设置为0.85.网页1、网页2至网页N表示所有链接指向A的网页。

    由以上公式可以看出三点:

    1、链接指向A的网页越多,A的级别越高。即A的级别和指向A的网页个数成正比,在公式中表示,N越大, A的级别越高;

    2、链接指向A的网页,其网页级别越高, A的级别也越高。即A的级别和指向A的网页自己的网页级别成正比,在公式中表示,网页N级别越高, A的级别也越高;

    3、链接指向A的网页,其链出的个数越多,A的级别越低。即A的级别和指向A的网页自己的网页链出个数成反比,在公式中现实,网页N链出个数越多,A的级别越低。

    每个网页有一个PageRank值,这样形成一个巨大的方程组,对这个方程组求解,就能得到每个网页的PageRank值。互联网上有上百亿个网页,那么这个方程组就有上百亿个未知数,这个方程虽然是有解,但计算毕竟太复杂了,不可能把这所有的页面放在一起去求解的。对具体的计算方法有兴趣的朋友可以去参考一些数值计算方面的书。

    总之,PageRank有效地利用了互联网所拥有的庞大链接构造的特性。 从网页A导向网页B的链接,用Google创始人的话讲,是页面A对页面B的支持投票,Google根据这个投票数来判断页面的重要性,但Google除了看投票数(链接数)以外,对投票者(链接的页面)也进行分析。「重要性」高的页面所投的票的评价会更高,因为接受这个投票页面会被理解为「重要的物品」。从新浪、雅虎、微软的首页都有我网页的三个链接的话,可能比我在其他网站找三十个链接还强。如果还有人不理解这个原理,就去想想有句成语叫:三人成虎。如果有三个人都说北京大街上有老虎,那么许多人会认为有老虎,如果这三个人都是国家领导人的话,那么所有人都会认为北京大街上有老虎。

    每个网页都会有PageRank值,如果大家想知道自己网站的网页PageRank值是多少,最简单的办法就是下载一个Google的免费工具栏

    每当你打开一个网页,都可以很清楚的看见此网页的PageRank值。当然这个值是一个大概数字。

    据Google技术负责人介绍,Google除了用PageRank衡量网页的重要程度以外,还有其它上百种因素来参与排序。其它搜索引擎也是如此,不可能按照某一种规则来进行搜索结果的排序。

    其他方法

    HillTop算法:

    HillTop同样是一项搜索引擎结果排序的专利,是Google的一个工程师Bharat在2001年获得的专利.Google的排序规则经常在变化,但变化最大的一次也就是基于HillTop算法进行了优化.HillTop究竟原理如何,值得Google如此青睐?

    其实HillTop算法的指导思想和PageRank的是一致的,都是通过网页被链接的数量和质量来确定搜索结果的排序权重。但HillTop 认为只计算来自具有相同主题的相关文档链接对于搜索者的价值会更大:即主题相关网页之间的链接对于权重计算的贡献比主题不相关的链接价值要更高。如果网站是介绍“服装”的,有10个链接都是从“服装”相关的网站链接过来,那这10个链接比另外10个从“电器”相关网站链接过来的贡献要大.Bharat称这种对主题有影响的文档为“专家”文档,从这些专家文档页面到目标文档的链接决定了被链接网页“权重得分”的主要部分。

    与PageRank结合HillTop算法确定网页与搜索关键词的匹配程度的基本排序过程取代了过份依靠PageRank的值去寻找那些权威页面的方法。这对于两个具有同样主题而且PR相近的网页排序过程中,HillTop算法就显得非常的重要了.HillTop同时也避免了许多想通过增加许多无效链接来提高网页PageRank值的做弊方法。

    锚文本(Anchor Text)

    锚文本名字听起来难以理解,实际上锚文本就是链接文本。例如,在个人网站上把中央电视台做为新闻频道的链接,访问者通过点击网站上的“新闻频道”就能进入央视网站,那么“新闻频道”就是中央电视台网站首页的锚文本。

    锚文本可以做为锚文本所在的页面的内容的评估。正常来讲,页面中增加的链接都会和页面本身的内容有一定的关系。服装的行业网站上会增加一些同行网站的链接或者一些做服装的知名企业的链接;另一方面,锚文本能做为对所指向页面的评估。锚文本能精确的描述所指向页面的内容,个人网站上增加 Google的链接,锚文本为“搜索引擎”。这样通过锚文本本身就能知道,Google是搜索引擎。

    锚文本对搜索引擎起的作用还表现为可以收集一些搜索引擎不能索引的文件。例如,网站上增加了一张张曼玉的照片,格式为jpg文件,搜索引擎目前很难索引(一般只处理文本)。若这张照片链接的锚文本为“张曼玉的照片”,那么搜索引擎就能识别这张图片是张曼玉的照片,以后访问者搜索“张曼玉”的时候,这张图片就能被搜索到。

    由此可见,在网页设计中选择合适的锚文本,会让所在网页和所指向网页的重要程度有所提升。

    页面版式

    每个网页都有版式,包括标题、字体、标签等等。搜索引擎也会利用这些版式来识别搜索词与页面内容的相关程度。以静态的html格式的网页为例, 搜索引擎通过网络蜘蛛把网页抓取下来后,需要提取里面的正文内容,过滤其他html代码。在提取内容的时候,搜索引擎就可以记录所有版式信息,包括:哪些词是在标题中出现,哪些词是在正文中出现,哪些词的字体比其他的字体大,哪些词是加粗过,哪些词是用KeyWord标识过的等等。这样在搜索结果中就可以根据这些信息来确定所搜索的结果和搜索词的相关程度。例如搜索“毛泽东”,假如有两个结果,一篇文章标题是《毛泽东的一生》,另一篇文章的标题是《江青的一生》但内容有提到毛泽东,这时搜索引擎会认为前者比较重要,因为“毛泽东”在标题里出现了。

    因此,合理的利用网页的页面版式,会提升网页在搜索结果页的排序位置。

    收费排名

    应该说收费排名并不属于排序技术(这里指的收费排名也包括竞价排名),而是一种搜索引擎的赢利模式。但收费排名已经最直接的影响到了搜索引擎的排序,在此也略做说明。

    用户可以购买某个关键词的排名,只要向搜索引擎公司交纳一定的费用,就可以让用户的网站排在搜索结果的前几位,按照不同关键词、不同位置、时间长短来定义价格。价格从几千元到几十万元不等(像“六合彩”在3721上的排名费用大多是几十万)。

    收费排名一方面给搜索引擎公司带来收益,一方面给企业带来访问量,另外对访问者也有一定好处。因为访问者想找“西服”,企业想卖“西服”,于是出钱让访问者能找到他,这样,买家和卖家能马上见面。但收费排名给访问者带来更多的却是不真实,结果排序已经失去了公正性,有时候还带来大量垃圾。在百度搜索引擎上搜索“星球”,排在第一位的是一家做石墨的公司,排在第二位的居然是“想找星球?上易趣吧!”(见下图)。真有些让访问者哭笑不得。

    当然,对于企业来说,收费排名是提升网站在搜索引擎中排名的最直接和最简单的办法。如今,如何提升网页在搜索引擎中的排序,已经形成了一门职业,叫SEO(Search Engine Optimization),即搜索引擎优化.SEO是针对搜索引擎排序的技术,通过修改网页(或者网站)结构和主动增加网站链接等方法来让搜索引擎认为这些网页是很重要的,从而提升网页在搜索引擎结果中的排序。

    排序技术的发展趋势

    各种搜索引擎的技术改进和优化,都直接反应到搜索结果的排序上。许多搜索引擎都在进一步研究新的排序方法,来提升客户的满意度。专业人士认为, 目前的搜索引擎排序算法上还存在两大不足一、没有真正解决相关性。相关性是指搜索词和页面的相关程度。仅仅通过链接、字体、位置等表面特征,不能真正判断搜索词和文章的相关性,更何况许多时候这些特征不会都同时存在。这也是许多对搜索引擎做弊方法能有效的原因。另外,有些文章中没有出现搜索词,但说的就是和搜索词十分相关的内容,例如搜索“恐怖分子”,但有网页是介绍本拉登的一些破坏行动,文中没有出现“恐怖分子”的子眼,搜索引擎就无法搜索到该网页。表面特征只能治标,不能治本。治本的方法应该是增加语意理解,例如主题词和关键词的提取,从语意上分析,得出搜索词和网页的相关程度,分析的越准,效果就会越好。

    二、搜索结果的单一化。在搜索引擎上,任何人搜索同一个词的结果都是一样。这样明显不能满足访问者。科学家搜索“星球”,可能是希望了解星球的知识,但普通人可能是想找“星球大战”电影,但搜索引擎所给的都是一样的结果。如何满足这些不同类型的访问者,需要对搜索结果的个性化。国外 vivisimo公司就是想解决这个问题,他们采用对搜索结果自动聚类的办法来满足不同类型客户的需要。搜索结果排序如果要实现从单一化到个性化,vivisimo已经迈出了一步,但最理想的结果应该是针对每个访问者,排序结果直接和他们的搜索习惯和意愿有关。搜索“体育”,对喜欢足球的人应该把足球的相关结果排在前面,对喜欢篮球的人应该把篮球的相关结果排在前面。

    搜索引擎的排序技术应该也会朝着解决这两个不足的方向发展:语意相关性和排序个性化。前者需要完善的自然语言处理技术,后者需要记录庞大访问者信息和复杂的计算,要达到其中任何一个的要求均非易事,如何解决这些难题,任务落在了科学家和工程师们的肩上,哪个搜索引擎解决了这些问题,她可能会称为下一个搜索世界的霸主。

  • MySQL中SQL的单字节注入与宽字节注入

    一、单字节SQL注入

    MYSQL的SQL注入已经由来已久,以下是普遍采用的注入步骤:

    1、在GET参数上加一个/*或者#(mysql专有的注释),判断数据库是否是mysql,比如:
    http://www.xxx.com.cn/article.php?id=1607 and 1=1/*

    2、猜解某表的字段数,从order by 1一直更改到页面出错为止,就可以得到该表的字段数

    注入URL:http://www.xxx.com.cn/article.php?id=1607 or 1=1 order by 10#

    对应的SQL: select * from articles where id=1607 or 1=1 order by 10#….
    3、使用该表和用户表进行关联查询,在文章列表里就可以看到用户名和密码了。当也要猜解用户表的表名和用户名、密码的字段名,比如上一步得到的字段数是5:

    注入的URL:http://www.xxx.com.cn/article.php?id=1607 or 1=1 union select  username,password,1,2,3 from user

    对应的SQL: select * from articles where id=1607 or 1=1  union select  username,password,1,2,3 from user
    这样就可以在界面上看到用户名和密码了。

    解决方法:

    过滤数据:这并不是罗唆。在合适的地方使用良好的数据过滤,可以减小多数安全隐患,甚至可以消除其中的一部分。

    将数据用括号包含:如果你的数据库允许(MySQL 允许),在 SQL 语句中,不论什么类型的数据都用单引号包含起来。

    转义数据:一些合法的数据可能在无意中破坏 SQL 语句本身的格式。使用 mysql_escape_string() 或者所使用数据库提供的转移函数。如果没有提供这样的函数,addslashes() 也是不错的最后选择。

    二、宽字节注入

    宽字节注入也是在最近的项目中发现的问题,大家都知道%df’ 被PHP转义(开启GPC、用addslashes函数,或者icov等),单引号被加上反斜杠\,变成了 %df\’,其中\的十六进制是 %5C ,那么现在 %df\’ = %df%5c%27,如果程序的默认字符集是GBK等宽字节字符集,则MYSQL用GBK的编码时,会认为 %df%5c 是一个宽字符,也就是縗’,也就是说:%df\’ = %df%5c%27=縗’,有了单引号就好注入了。比如:

    以下为引用的内容:

    $conn = mysql_connect(”localhost”,”root”,”2sdfxedd”);
    mysql_query(”SET NAMES ‘GBK’”);
    mysql_select_db(”test”,$conn);
    $user = mysql_escape_string($_GET[‘user’]);
    $pass = mysql_escape_string($_GET[‘pass’]);
    $sql = “select * from cms_user where username = ‘$user’ and password=’$pass’”;
    $result = mysql_query($sql,$conn);
    while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
    $rows[] = $row;
    }
    ?>
     

     

    则通过以下注入即可:

    http://www.xxx.com/login.php?user=%df’%20or%201=1%20limit%201,1%23&pass=

    对应的SQL是:

    select * from cms_user where username = ‘運’ or 1=1 limit 1,1#’ and password=”

    解决方法:就是在初始化连接和字符集之后,使用SET character_set_client=binary来设定客户端的字符集是二进制的。如:

    以下为引用的内容:

    mysql_query(”SET character_set_client=binary”);

  • 猴王算法

    <?php
    /*
    * filename: kingmonkey.php
    * author: jiangang li
    * date: April 3th, 2009
    * descript: an arithmetic to a program
    * program: 
       一群猴子排成一圈,按1,2,…,n依次编号。 
       然后从第1只开始数,数到第m只,把它踢出圈,
       从它后面再开始数,  再数到第m只,在把它踢出去…,
       如此不停的进行下去,  直到最后只剩下一只猴子为止,那只猴子就叫做大王。 
       要求编程模拟此过程,输入m、n, 输出最后那个大王的编号。
    */
    set_time_limit(1);
    function KingMokey($n, $m)
    {
            //将1-n只猴子顺序编号 入数组中
      $monkey = range(1,$n);
            //循环遍历数组元素(猴子编号)
      $i=1;
      while(1){
       list($key,$value)=each($monkey);
       if (!$value){
        reset($monkey);
        list($key,$value)=each($monkey);
       }
       if(count($monkey)==1){
        break;
       }
       if ($i%$m == 0){
        unset($monkey[$key]);
       }
       $i = $i % $m + 1;
      }
      return $value;
    }
    //猴子个数
    $n = 10;
    //踢出队伍的编号间隔值
    $m = 3;
    //调用猴王获取函数
    print_r(KingMokey($n, $m));
    ?>

  • 用php或js获取图片大小高宽尺寸

    <?
    arr=getimagesize(“images/album_01.gif”);
    echo arr[3];
    strarr=explode(“””,arr[3]);
    echo strarr[1];
    ?>

    <HTML>
    <HEAD>
    <TITLE>演示图片等比例缩小</TITLE>
    <script>
    function Wa_SetImgAutoSize(img)
    {
    //var img=document.all.img1;//获取图片
    var MaxWidth=200;//设置图片宽度界限
    var MaxHeight=100;//设置图片高度界限
    var HeightWidth=img.offsetHeight/img.offsetWidth;//设置高宽比
    var WidthHeight=img.offsetWidth/img.offsetHeight;//设置宽高比
    alert(“test”+img.offsetHeight+img.fileSize);
    if(img.offsetHeight>1) alert(img.offsetHeight);
    if(img.readyState!=”complete”){
    return false;//确保图片完全加载
    }

    if(img.offsetWidth>MaxWidth){
    img.width=MaxWidth;
    img.height=MaxWidth*HeightWidth;
    }
    if(img.offsetHeight>MaxHeight){
    img.height=MaxHeight;
    img.width=MaxHeight*WidthHeight;
    }
    }

    function CheckImg(img)
    {
    var message=””;
    var MaxWidth=1;//设置图片宽度界限
    var MaxHeight=1;//设置图片高度界限

    if(img.readyState!=”complete”){
    return false;//确保图片完全加载
    }
    if(img.offsetHeight>MaxHeight) message+=”r高度超额:”+img.offsetHeight;
    if(img.offsetWidth>MaxWidth) message+=”r宽度超额:”+img.offsetWidth;
    if(message!=””) alert(message);
    }
    </script>
    </HEAD>
    <BODY>
    <img src=”images/frequency.gif” border=0 id=”img1″ onload=”CheckImg(this);”>
    <br>
    <input id=inp type=”file” onpropertychange=”img1.src=this.value;”>
    </BODY>
    </HTML>

  • php大文件上传经典源码

    function function_upload($name,$newname=””,$dir=”upload”)
    {
     global $_FILES,$ext;

     $return=””;

     $time=time();

     $upload=trim($_FILES[$name][‘tmp_name’]);

     $upload_name=trim($_FILES[$name][‘name’]);

     $size=trim($_FILES[$name][‘size’]);

     if(empty($upload) or empty($upload_name) or $size==0)
     {
      return $return;
     }

     $dir.=”/”.date(“Y-m”,$time);

     if (is_uploaded_file($upload))
     {
      $ext=file_extension($upload_name);

      if(liu_mkdir($dir))
      {
      
       if($newname!=””)
       {
       
        $newname.=”.”.$ext;
        //$newname=TIME_NOW.”.”.$ext;
       }else{
        //$newname=$upload_name;
        $newname=$time.”.”.$ext;
       }

       if(move_uploaded_file($upload,$dir.”/”.$newname) and file_exists($dir.”/”.$newname))
       {
        chmod($dir.”/”.$newname,0755);
        $return=$dir.”/”.$newname;
       }
      }

     }

     return $return;

    }

    function file_extension($filename)
    {
     return substr(strrchr($filename, ‘.’), 1);
    }

    function liu_mkdir($dir,$mode=0777)
    {
     if(is_dir($dir))
     {

      if(!is_writable($dir))
      {

       @chmod($dir,$mode);

      }
      return true;
     }
     else
     
     {

      $oldmask = @umask(0);

      $partialpath = dirname($dir);

      if(!liu_mkdir($partialpath,$mode))
      {

       return false;

      }
      else

      {
       return mkdir($dir,$mode);
      }

     }
    }

  • PHP生成中文拼音

    <?php
    class ChineseSpell {
     /**
      * @var array $chineseSpellList 拼音编码对应表
      * @access private
      */
     private $chineseSpellList = array(
        ‘a’=>-20319,
        ‘ai’=>-20317,
        ‘an’=>-20304,
        ‘ang’=>-20295,
        ‘ao’=>-20292,
        ‘ba’=>-20283,
        ‘bai’=>-20265,
        ‘ban’=>-20257,
        ‘bang’=>-20242,
        ‘bao’=>-20230,
        ‘bei’=>-20051,
        ‘ben’=>-20036,
        ‘beng’=>-20032,
        ‘bi’=>-20026,
        ‘bian’=>-20002,
        ‘biao’=>-19990,
        ‘bie’=>-19986,
        ‘bin’=>-19982,
        ‘bing’=>-19976,
        ‘bo’=>-19805,
        ‘bu’=>-19784,
        ‘ca’=>-19775,
        ‘cai’=>-19774,
        ‘can’=>-19763,
        ‘cang’=>-19756,
        ‘cao’=>-19751,
        ‘ce’=>-19746,
        ‘ceng’=>-19741,
        ‘cha’=>-19739,
        ‘chai’=>-19728,
        ‘chan’=>-19725,
        ‘chang’=>-19715,
        ‘chao’=>-19540,
        ‘che’=>-19531,
        ‘chen’=>-19525,
        ‘cheng’=>-19515,
        ‘chi’=>-19500,
        ‘chong’=>-19484,
        ‘chou’=>-19479,
        ‘chu’=>-19467,
        ‘chuai’=>-19289,
        ‘chuan’=>-19288,
        ‘chuang’=>-19281,
        ‘chui’=>-19275,
        ‘chun’=>-19270,
        ‘chuo’=>-19263,
        ‘ci’=>-19261,
        ‘cong’=>-19249,
        ‘cou’=>-19243,
        ‘cu’=>-19242,
        ‘cuan’=>-19238,
        ‘cui’=>-19235,
        ‘cun’=>-19227,
        ‘cuo’=>-19224,
        ‘da’=>-19218,
        ‘dai’=>-19212,
        ‘dan’=>-19038,
        ‘dang’=>-19023,
        ‘dao’=>-19018,
        ‘de’=>-19006,
        ‘deng’=>-19003,
        ‘di’=>-18996,
        ‘dian’=>-18977,
        ‘diao’=>-18961,
        ‘die’=>-18952,
        ‘ding’=>-18783,
        ‘diu’=>-18774,
        ‘dong’=>-18773,
        ‘dou’=>-18763,
        ‘du’=>-18756,
        ‘duan’=>-18741,
        ‘dui’=>-18735,
        ‘dun’=>-18731,
        ‘duo’=>-18722,
        ‘e’=>-18710,
        ‘en’=>-18697,
        ‘er’=>-18696,
        ‘fa’=>-18526,
        ‘fan’=>-18518,
        ‘fang’=>-18501,
        ‘fei’=>-18490,
        ‘fen’=>-18478,
        ‘feng’=>-18463,
        ‘fo’=>-18448,
        ‘fou’=>-18447,
        ‘fu’=>-18446,
        ‘ga’=>-18239,
        ‘gai’=>-18237,
        ‘gan’=>-18231,
        ‘gang’=>-18220,
        ‘gao’=>-18211,
        ‘ge’=>-18201,
        ‘gei’=>-18184,
        ‘gen’=>-18183,
        ‘geng’=>-18181,
        ‘gong’=>-18012,
        ‘gou’=>-17997,
        ‘gu’=>-17988,
        ‘gua’=>-17970,
        ‘guai’=>-17964,
        ‘guan’=>-17961,
        ‘guang’=>-17950,
        ‘gui’=>-17947,
        ‘gun’=>-17931,
        ‘guo’=>-17928,
        ‘ha’=>-17922,
        ‘hai’=>-17759,
        ‘han’=>-17752,
        ‘hang’=>-17733,
        ‘hao’=>-17730,
        ‘he’=>-17721,
        ‘hei’=>-17703,
        ‘hen’=>-17701,
        ‘heng’=>-17697,
        ‘hong’=>-17692,
        ‘hou’=>-17683,
        ‘hu’=>-17676,
        ‘hua’=>-17496,
        ‘huai’=>-17487,
        ‘huan’=>-17482,
        ‘huang’=>-17468,
        ‘hui’=>-17454,
        ‘hun’=>-17433,
        ‘huo’=>-17427,
        ‘ji’=>-17417,
        ‘jia’=>-17202,
        ‘jian’=>-17185,
        ‘jiang’=>-16983,
        ‘jiao’=>-16970,
        ‘jie’=>-16942,
        ‘jin’=>-16915,
        ‘jing’=>-16733,
        ‘jiong’=>-16708,
        ‘jiu’=>-16706,
        ‘ju’=>-16689,
        ‘juan’=>-16664,
        ‘jue’=>-16657,
        ‘jun’=>-16647,
        ‘ka’=>-16474,
        ‘kai’=>-16470,
        ‘kan’=>-16465,
        ‘kang’=>-16459,
        ‘kao’=>-16452,
        ‘ke’=>-16448,
        ‘ken’=>-16433,
        ‘keng’=>-16429,
        ‘kong’=>-16427,
        ‘kou’=>-16423,
        ‘ku’=>-16419,
        ‘kua’=>-16412,
        ‘kuai’=>-16407,
        ‘kuan’=>-16403,
        ‘kuang’=>-16401,
        ‘kui’=>-16393,
        ‘kun’=>-16220,
        ‘kuo’=>-16216,
        ‘la’=>-16212,
        ‘lai’=>-16205,
        ‘lan’=>-16202,
        ‘lang’=>-16187,
        ‘lao’=>-16180,
        ‘le’=>-16171,
        ‘lei’=>-16169,
        ‘leng’=>-16158,
        ‘li’=>-16155,
        ‘lia’=>-15959,
        ‘lian’=>-15958,
        ‘liang’=>-15944,
        ‘liao’=>-15933,
        ‘lie’=>-15920,
        ‘lin’=>-15915,
        ‘ling’=>-15903,
        ‘liu’=>-15889,
        ‘long’=>-15878,
        ‘lou’=>-15707,
        ‘lu’=>-15701,
        ‘lv’=>-15681,
        ‘luan’=>-15667,
        ‘lue’=>-15661,
        ‘lun’=>-15659,
        ‘luo’=>-15652,
        ‘ma’=>-15640,
        ‘mai’=>-15631,
        ‘man’=>-15625,
        ‘mang’=>-15454,
        ‘mao’=>-15448,
        ‘me’=>-15436,
        ‘mei’=>-15435,
        ‘men’=>-15419,
        ‘meng’=>-15416,
        ‘mi’=>-15408,
        ‘mian’=>-15394,
        ‘miao’=>-15385,
        ‘mie’=>-15377,
        ‘min’=>-15375,
        ‘ming’=>-15369,
        ‘miu’=>-15363,
        ‘mo’=>-15362,
        ‘mou’=>-15183,
        ‘mu’=>-15180,
        ‘na’=>-15165,
        ‘nai’=>-15158,
        ‘nan’=>-15153,
        ‘nang’=>-15150,
        ‘nao’=>-15149,
        ‘ne’=>-15144,
        ‘nei’=>-15143,
        ‘nen’=>-15141,
        ‘neng’=>-15140,
        ‘ni’=>-15139,
        ‘nian’=>-15128,
        ‘niang’=>-15121,
        ‘niao’=>-15119,
        ‘nie’=>-15117,
        ‘nin’=>-15110,
        ‘ning’=>-15109,
        ‘niu’=>-14941,
        ‘nong’=>-14937,
        ‘nu’=>-14933,
        ‘nv’=>-14930,
        ‘nuan’=>-14929,
        ‘nue’=>-14928,
        ‘nuo’=>-14926,
        ‘o’=>-14922,
        ‘ou’=>-14921,
        ‘pa’=>-14914,
        ‘pai’=>-14908,
        ‘pan’=>-14902,
        ‘pang’=>-14894,
        ‘pao’=>-14889,
        ‘pei’=>-14882,
        ‘pen’=>-14873,
        ‘peng’=>-14871,
        ‘pi’=>-14857,
        ‘pian’=>-14678,
        ‘piao’=>-14674,
        ‘pie’=>-14670,
        ‘pin’=>-14668,
        ‘ping’=>-14663,
        ‘po’=>-14654,
        ‘pu’=>-14645,
        ‘qi’=>-14630,
        ‘qia’=>-14594,
        ‘qian’=>-14429,
        ‘qiang’=>-14407,
        ‘qiao’=>-14399,
        ‘qie’=>-14384,
        ‘qin’=>-14379,
        ‘qing’=>-14368,
        ‘qiong’=>-14355,
        ‘qiu’=>-14353,
        ‘qu’=>-14345,
        ‘quan’=>-14170,
        ‘que’=>-14159,
        ‘qun’=>-14151,
        ‘ran’=>-14149,
        ‘rang’=>-14145,
        ‘rao’=>-14140,
        ‘re’=>-14137,
        ‘ren’=>-14135,
        ‘reng’=>-14125,
        ‘ri’=>-14123,
        ‘rong’=>-14122,
        ‘rou’=>-14112,
        ‘ru’=>-14109,
        ‘ruan’=>-14099,
        ‘rui’=>-14097,
        ‘run’=>-14094,
        ‘ruo’=>-14092,
        ‘sa’=>-14090,
        ‘sai’=>-14087,
        ‘san’=>-14083,
        ‘sang’=>-13917,
        ‘sao’=>-13914,
        ‘se’=>-13910,
        ‘sen’=>-13907,
        ‘seng’=>-13906,
        ‘sha’=>-13905,
        ‘shai’=>-13896,
        ‘shan’=>-13894,
        ‘shang’=>-13878,
        ‘shao’=>-13870,
        ‘she’=>-13859,
        ‘shen’=>-13847,
        ‘sheng’=>-13831,
        ‘shi’=>-13658,
        ‘shou’=>-13611,
        ‘shu’=>-13601,
        ‘shua’=>-13406,
        ‘shuai’=>-13404,
        ‘shuan’=>-13400,
        ‘shuang’=>-13398,
        ‘shui’=>-13395,
        ‘shun’=>-13391,
        ‘shuo’=>-13387,
        ‘si’=>-13383,
        ‘song’=>-13367,
        ‘sou’=>-13359,
        ‘su’=>-13356,
        ‘suan’=>-13343,
        ‘sui’=>-13340,
        ‘sun’=>-13329,
        ‘suo’=>-13326,
        ‘ta’=>-13318,
        ‘tai’=>-13147,
        ‘tan’=>-13138,
        ‘tang’=>-13120,
        ‘tao’=>-13107,
        ‘te’=>-13096,
        ‘teng’=>-13095,
        ‘ti’=>-13091,
        ‘tian’=>-13076,
        ‘tiao’=>-13068,
        ‘tie’=>-13063,
        ‘ting’=>-13060,
        ‘tong’=>-12888,
        ‘tou’=>-12875,
        ‘tu’=>-12871,
        ‘tuan’=>-12860,
        ‘tui’=>-12858,
        ‘tun’=>-12852,
        ‘tuo’=>-12849,
        ‘wa’=>-12838,
        ‘wai’=>-12831,
        ‘wan’=>-12829,
        ‘wang’=>-12812,
        ‘wei’=>-12802,
        ‘wen’=>-12607,
        ‘weng’=>-12597,
        ‘wo’=>-12594,
        ‘wu’=>-12585,
        ‘xi’=>-12556,
        ‘xia’=>-12359,
        ‘xian’=>-12346,
        ‘xiang’=>-12320,
        ‘xiao’=>-12300,
        ‘xie’=>-12120,
        ‘xin’=>-12099,
        ‘xing’=>-12089,
        ‘xiong’=>-12074,
        ‘xiu’=>-12067,
        ‘xu’=>-12058,
        ‘xuan’=>-12039,
        ‘xue’=>-11867,
        ‘xun’=>-11861,
        ‘ya’=>-11847,
        ‘yan’=>-11831,
        ‘yang’=>-11798,
        ‘yao’=>-11781,
        ‘ye’=>-11604,
        ‘yi’=>-11589,
        ‘yin’=>-11536,
        ‘ying’=>-11358,
        ‘yo’=>-11340,
        ‘yong’=>-11339,
        ‘you’=>-11324,
        ‘yu’=>-11303,
        ‘yuan’=>-11097,
        ‘yue’=>-11077,
        ‘yun’=>-11067,
        ‘za’=>-11055,
        ‘zai’=>-11052,
        ‘zan’=>-11045,
        ‘zang’=>-11041,
        ‘zao’=>-11038,
        ‘ze’=>-11024,
        ‘zei’=>-11020,
        ‘zen’=>-11019,
        ‘zeng’=>-11018,
        ‘zha’=>-11014,
        ‘zhai’=>-10838,
        ‘zhan’=>-10832,
        ‘zhang’=>-10815,
        ‘zhao’=>-10800,
        ‘zhe’=>-10790,
        ‘zhen’=>-10780,
        ‘zheng’=>-10764,
        ‘zhi’=>-10587,
        ‘zhong’=>-10544,
        ‘zhou’=>-10533,
        ‘zhu’=>-10519,
        ‘zhua’=>-10331,
        ‘zhuai’=>-10329,
        ‘zhuan’=>-10328,
        ‘zhuang’=>-10322,
        ‘zhui’=>-10315,
        ‘zhun’=>-10309,
        ‘zhuo’=>-10307,
        ‘zi’=>-10296,
        ‘zong’=>-10281,
        ‘zou’=>-10274,
        ‘zu’=>-10270,
        ‘zuan’=>-10262,
        ‘zui’=>-10260,
        ‘zun’=>-10256,
        ‘zuo’=>-10254
        );
     
     /**
      * 取汉字所有拼音
      * @param string $chinese 要转换的汉字
      * @param string $delimiter 分隔符
      * @param int $length 返回的长度
      * @return string
      */
     public function getFullSpell($chinese, $delimiter = ‘ ‘, $length = 0) {
      $spell = $this->getChineseSpells($chinese, $delimiter);
      if ($length) {
       $spell = substr($spell, 0, $length);
      }
      return $spell;
     }
     
     /**
      * 取汉字第一个拼音
      * @param string $chinese 要转换的汉字
      * @param int $length 返回的长度
      * @return string
      */
     public function getFirstSpell($chinese, $length = 0) {
      $spell = $this->getChineseSpells($chinese, ‘ ‘, 1);
      if ($length) {
       $spell = substr($spell, 0, $length);
      }
      return $spell;
     }
     /**
      * 取一个汉字码对应的拼音
      * @param int $num 汉字码
      * @param string $blank 空白字符
      * @return string
      */
     private function getChineseSpell ($num, $blank = ”) {
      if ( $num>0 && $num<160 ) {
       return chr($num);
      } elseif ($num<-20319||$num>-10247) {
       return $blank;
      } else {
       foreach ($this->chineseSpellList as $spell => $code) {
        if ($code > $num) break;
        $result = $spell;
       }
       return $result;
      }
     }
     /**
      * 取汉字拼音
      * @param string $chinese 要转换的汉字
      * @param string $delimiter 分隔符
      * @param int $first 是否只返回第一个
      * @return string
      */
     private function getChineseSpells($chinese, $delimiter = ‘ ‘, $first=0)
     {
      $result = array();
      for ($i=0; $i<strlen($chinese); $i++) {
       $p = ord(substr($chinese,$i,1));
       if ($p>160) {
        $q = ord(substr($chinese,++$i,1));
        $p = $p*256 + $q – 65536;
       }
       $result[] = $this->getChineseSpell($p);
       if ($first) {
        return $result[0];
       }
      }
      return implode($delimiter, $result);
     }
    }
    ?>

  • php代码防注入事例

    今天写代码的时候猛然想到是不能能够通过一个文件来处理整个网站中所有可能出现注入的地方进行防范呢?这样就能够不用在每个程序里对每个变量进行过滤,节省了时间和代码。

    我们主要是从两点出发,因为我们的获取的变量一般都是通过GET或者POST方式提交过来的,那么我们只要对GET和POST过来的变量进行过滤,那么就能够达到防止注入的效果。而且我们的PHP真是非常好,已经内置了$_GET和$_POST两个数组来存储所有变量,我们要做的工作就是过滤每个变量就可以了。
    下面看具体的代码:

    php代码:

    以下为引用的内容:
    /*
    PHP118= 全球最大的PHP中文社群 = PHPer的网上家园
    */

    /* Author: heiyeluren */
    /* 过滤所有GET过来变量 */
    foreach ($_GET as $get_key=%26gt;$get_var)
    {
    if (is_numeric($get_var))
    if (is_numeric($get_var)) {
    $get[strtolower($get_key)] = get_int($get_var);
    } else {
    $get[strtolower($get_key)] = get_str($get_var);
    }
    }

    /* 过滤所有POST过来的变量 */
    foreach ($_POST as $post_key=%26gt;$post_var)
    {
    if (is_numeric($post_var)) {
    $post[strtolower($post_key)] = get_int($post_var);
    } else {
    $post[strtolower($post_key)] = get_str($post_var);
    }
    }

    /* 过滤函数 */
    //整型过滤函数
    function get_int($number)
    {
    return intval($number);
    }
    //字符串型过滤函数
    function get_str($string)
    {
    if (!get_magic_quotes_gpc()) {
    return addslashes($string);
    }
    return $string;
    }
     
    那么我们把以上代码放到一个公共的文件里,比如security.inc.php里面,每个文件里都include一下这个文件,那么就能够给任何一个程序进行提交的所有变量进行过滤了,就达到了我们一劳永逸的效果。

  • PHP下载文件名乱码问题详解

    通过把Content-Type设置为application/octet-stream,可以把动态生成的内容当作文件来下载,相信这个大家都会。那么用Content-Disposition设置下载的文件名,这个也有不少人知道吧。基本上,下载程序都是这么写的:

    header(‘Content-Disposition: attachment; filename=’ . $filename);print “Hello!”;?> 

    这样用浏览器打开之后,就可以下载document.txt。

    但是,如果$filename是UTF-8编码的,有些浏览器就无法正常处理了。比如把上面那个程序稍稍改一下:

    header(‘Content-Disposition: attachment; filename=’ . $filename);print “Hello!”;?>  

    把程序保存成UTF-8编码再访问,IE6下载的文件名就会乱码。 FF3下下载的文件名就只有“中文”两个字。Opera 9下一切正常。

    输出的header实际上是这样子:

    Content-Disposition: attachment; filename=中文 文件名.txt
    其实按照RFC2231的定义,多语言编码的Content-Disposition应该这么定义:

    Content-Disposition: attachment; filename*=”utf8”%E4%B8%AD%E6%96%87%20%E6%96%87%E4%BB%B6%E5%90%8D.txt”

    即:

    filename后面的等号之前要加 * filename的值用单引号分成三段,分别是字符集(utf8)、语言(空)和urlencode过的文件名。 最好加上双引号,否则文件名中空格后面的部分在Firefox中显示不出来 注意urlencode的结果与php的urlencode函数结果不太相同,php的urlencode会把空格替换成+,而这里需要替换成%20

    经过试验,发现几种主流浏览器的支持情况如下:

    IE6 attachment; filename=””

    FF3 attachment; filename=”UTF-8文件名”

    attachment; filename*=”utf8””

    O9 attachment; filename=”UTF-8文件名”

    Safari3(Win) 貌似不支持?上述方法都不行

    这样看来,程序必须得这样写才能支持所有主流浏览器:

    以下为引用的内容:

    $encoded_filename = urlencode($filename);$encoded_filename = str_replace(“+”, “%20”, $encoded_filename);header(‘Content-Type: application/octet-stream’);if (preg_match(“/MSIE/”, $ua)) { header(‘Content-Disposition: attachment; filename=”‘ . $encoded_filename . ‘”‘);} else if (preg_match(“/Firefox/”, $ua)) { header(‘Content-Disposition: attachment; filename*=”utf8\’\” . $filename . ‘”‘);} else { header(‘Content-Disposition: attachment; filename=”‘ . $filename . ‘”‘);}print ‘ABC’;?>

  • Joomla! v1.5.10 Final

    Joomla!是一套在国外相当知名的内容管理系统(Content Management System – CMS),它属于Portal(企业入口网站)类型,顾名思义,就是比较适合作为商业类型的网站程序.它是开源的!Joomla!是使用PHP语言加上 MySQL数据库所开发的软件系统,可以在Linux、Windows、MacOSX等各种不同的平台上执行.

    Joomla!是使用PHP语言加上MySQL数据库所开发的软件系统,可以在Linux、Windows、MacOSX等各种不同的平台上执行。目前是由Open Source Matters (www.opensourcematters.org)这个开放源码组织进行开发与支持,这个组织的成员来自全世界各地,小组成员约有150人,包含了开发者、设计者、系统管理者、文件撰写者,以及超过2万名的参与会员。

    官网:http://www.joomla.org

  • 最简单删除SQL Server中所有数据的方法

    其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间可能形成相互约束关系,删除操作可能陷入死循环,二是这里使用了微软未正式公开的sp_MSForEachTable存储过程。

    也许很多读者朋友都经历过这样的事情:要在开发数据库基础上清理一个空库,但由于对数据库结构缺乏整体了解,在删除一个表的记录时,删除不了,因为可能有外键约束,一个常见的数据库结构是一个主表,一个子表,这种情况下一般都得先删除子表记录,再删除主表记录。
    说道删除数据记录,往往马上会想到的是delete和truncate语句,但在遇到在两个或多个表之间存在约束的话,这两个语句可能都会失效,而且最要命的是这两个命令都只能一次操作一个表。那么真正遇到要删除SQL Server数据库中所有记录时,该怎么办呢?有两个选择:

    1.按照先后顺序逐个删除,这个方法在表非常多的情况下显得很不现实,即便是表数量不多,但约束比较多时,你还是要花费大量的时间和精力去研究其间的约束关系,然后找出先删哪个表,再删哪个表,最后又删哪个表。

    2.禁用所有约束,删除所有数据,最后再启用约束,这样就不用花时间和精力去研究什么约束了,只需要编写一个简单的存储过程就可以自动完成这个任务。
    从这两个选择中不难看出第二个选择是最简单有效的了,那么在使用第二个选择时,具体该怎么实施呢?

    首先得编写代码循环检查所有的表,这里我推荐一个存储过程sp_MSForEachTable,因为在微软的官方文档中没有对这个存储过程有描述,很多开发人员也许都还未曾听说,所以你在互联网上搜索得到的解决办法大多很复杂,也许有的人会认为,既然没有官方文档,这个存储过程可能会不稳定,打心理上会排斥它,但事实并非如此。下面来先看一个完整的脚本:
    CREATE PROCEDURE sp_DeleteAllDataASEXEC sp_MSForEachTable ‘ALTER TABLE ? NOCHECK CONSTRAINT ALL’EXEC sp_MSForEachTable ‘ALTER TABLE ? DISABLE TRIGGER ALL’EXEC sp_MSForEachTable ‘DELETE FROM ?’EXEC sp_MSForEachTable ‘ALTER TABLE ? CHECK CONSTRAINT ALL’EXEC sp_MSForEachTable ‘ALTER TABLE ? ENABLE TRIGGER ALL’EXEC sp_MSFOREACHTABLE ‘SELECT * FROM ?’GO
    这个脚本创建了一个命名为sp_DeleteAllData的存储过程,前面两行语句分别禁用约束和触发器,第三条语句才是真正地删除所有数据,接下里的语句分别还原约束和触发器,最后一条语句是显示每个表中的记录,当然这条语句也可以不要,我只是想确认一下是否清空了所有表而已。

    你可以在任何数据库上运行这个存储过程,当然不要在生成数据库上运行,可别怪我没告诉你!不管怎样,还是先备份一下数据库,使用备份数据库还原,然后再运行该存储过程,呵呵,即使是一个大型数据库,也要不多长时间,你的数据库就成一个空库了,有点怕怕的感觉!

  • wp_options数据表优化和清理垃圾数据

      wp_options 这个数据表是wordpress全局数据,这个表会经常有数据膨胀,而且会残留以前用过的一些插件或者什么的残留数据,另外就是占用数据的大户RSS缓存,后台的数据调用竟然会放到数据库里面,所以删除RSS_前缀的数据就可以清除大部分地方,另外还有一款插件可以清除wp_options 里面的垃圾数据,我发在下面,网上对RSS处理方法有两种一个是修改后台的文件直接不去调用,这个是我不喜欢的毕竟修改了程序,其实这个很容易忘记WP升级是太频繁的哪次更新覆盖了新文件还是照样缓存进板另外一种就是在配置文件里面填写
    define(‘MAGPIE_CACHE_ON’, ‘0’);  这个是管用的我添加以后后台首页的调用明显变慢 ,查看数据库数据没有在变大写入进去了.

    清除wp_options的插件
    WordPress Clean Options Plugin:
    http://www.mittineague.com/dev/co.php

  • Internet Explorer 8.0

      看来8.0快出来了,最近马上要放出RC版,以后的浏览器应该会越来越接近网页标准了,据说IE6是对网页标准很不尊重的,这导致很多人的网页编写都不是规范的,不过在7以后的版本微软都是比较尊重W3C的都在一步一步的接近标准,8.0正式版以后准备就直接用8.0了,7.0也是用过一段时间的,现在在用6.0,其实网页如果就一个标准的话,我更愿意用6,不支持多页面打开还是挺快的,安装工具条以后可以辅助一些功能,而在7.0或者更高的版本上就是鸡肋了,竞争虽然是刺激进步,但是这些遗留问题也挺不爽的。

    beta1版本推出了模拟IE7的模式、增加了在线邮件浏览功能、提高了兼容性、反钓鱼功能进一步增强,可以进行 网页地址筛选。北京时间8月28日消息,据国外媒体报道,微软周三发布了功能完备的升级版IE8 Beta 2。微软称,IE8 Beta 2的新特性是加强了隐私保护,并提高了使用舒适性及安全性。微软3月份发布了IE8 Beta 1,但目的只是向网络开发者展示这一最新IE版本,Beta 2则旨在向更多用户进行展示。微软没有透露将于何时正式推出IE8,也并未对会有多少用户下载Beta 2作出预测。

  • 关于使用定时发布文章的一些经验

       呵呵,目前尝试发布了定时文章,为我以后没有时间发文章来做准备,使用效果是很不错的,感觉WORDPRESS是个非常棒的系统,我一定要拜读wordpress的所有代码,发布这样的文章,我担心的主要有两点,如果我一次发布过多文章,等我有空的时候,定时文章还在发布,我即时发布的文章会出现ID的顺序错乱,这个不知道会不会对引擎造成困扰,第二个就是定时发布的文章会不会使用RPC通知,在定时文章发布后,确认应该是通知的,在定时发布文章10分钟后我有意SITE了一下,发现实时更新了,于是很是高兴,决定开始使用,哈哈,不知道搜索引擎看到我的文章会不会感慨呢。

  • WP Cleaner 删除wordpress不再需要的修订版

    之前发布过一篇关于删除历史文章的文章,今天又看到这个插件好奇的用了下,没想到还有残留的文章,于是又清理了一下,不知道是文章哪里写的不错,还是我操作的时候少操作了什么,总之先发出这个插件吧,用这个的话会简单的多的。

    名称:WP Cleaner
    版本: 1.0
    作者:JiangMiao
    兼容:Wordpress 2.7
    更新:2008-12-16
    描述:删除不再需要的修订版或草稿,减小空间,提高性能。
    性能:本插件有保护机制,无论怎么操作都无法影响已发布的贴子,请放心使用^^

    安装方法:

    1. 复制目录wpcleaner到 /wp-content/plugins/ 或用’添加新插件’功能上传压缩包。
    2. 激活本插件
    3. 在WP Cleaner设置页进行相关操作
    4. 若不再使用,直接禁用或删除即可。

    官方地址:http://www.jiangmiao.org/blog/138.html

    本站提供下载地址:更新版本修改WP Cleaner短标签语句

  • wordpress定时发布文章功能

      其实已经不止一次的看到类似文章了,不过都没有真正的投入使用,每天都坚持实时更新,做到天天写天天更新,不过以后可能会有些麻烦了,时间上可能会出现一些问题,毕竟博客只是生活的一小部分,不可能这么精心的去顾及这个东西。

     今天又一次看到有人在说这个功能,突然是有恍然大悟的感觉,当精力旺盛的时候更新多几篇文章来做箱底,在没有时间的时候就让他们定时发布吧,我想这是个不错的主意呵呵。

    至于详细的时候我就不在赘述了,网上很多在说,而且使用也是简单的不得了,我的网址结构是用 分类/ID/文章名 定时发布可能会出现ID不顺序的显像,我想问题也是不大的。

  • wordpress rpc 更新服务

      相信用WP的用户应该有体会,就是发布文章过后,google收录可以快到1分钟之前,也就是说发布完文章后google马上就收录,我之前已经不止一次的发现这样如此快速的收录,而其他程序则google很不感冒每天更新成百上千的文章google也不爬你一下,我想很大程度应该wordpress RPC的更新服务关系吧。

    默认下是只有一个地址:http://rpc.pingomatic.com/

    但是我在官方的说明页面又加入了一些,这样才使更新如此之快的吧。RPC列表:

    http://api.moreover.com/ping
    http://api.my.yahoo.com/rss/ping
    http://blogsearch.google.com/ping/RPC2
    http://ping.bitacoras.com
    http://ping.feedburner.com
    http://ping.syndic8.com/xmlrpc.php
    http://rpc.blogrolling.com/pinger/
    http://rpc.icerocket.com:10080/
    http://rpc.technorati.com/rpc/ping
    http://rpc.weblogs.com/RPC2
    http://topicexchange.com/RPC2
    http://www.blogdigger.com/RPC2
    http://www.blogoole.com/ping/
    http://www.popdex.com/addsite.php
    http://www.wasalive.com/ping/
    http://www.weblogues.com/RPC/
    http://blogping.unidatum.com/RPC2/

    今天又看了下,似乎有人更新了页面并且又提供了一大列PRC,我没有更新他说的是2年前收集的并且不知道哪个是生效的,我本着宁缺毋滥的想法,只添加了三个,是国内的列表看了网址大概就知道是哪个网站了。

    http://www.xianguo.com/xmlrpc/ping.php
    http://www.zhuaxia.com/rpc/server.php
    http://blog.youdao.com/ping/RPC2

  • 研究表明俄罗斯方块有助于排解忧愁(附HTML源代码)

    俄罗斯方块我是玩的,排解忧愁不否认,不过这个游戏我玩多了晚上睡觉都会有方块的。

    据香港《大公报》报道,遭受重大打击后,玩《俄罗斯方块》(Tetris)可以减低创伤后压力症的征状.
    英国研究人员发现,遭受创伤后不久玩《俄罗斯方块》有助抹去痛苦记忆和减少不快的回忆突然重现的频率.这项发现可以帮助科学家找到新方法去治疗因为意外入 院或是从战区回来的人士.研究人员向40名健康的志愿人士展示不同来源的创伤性影像,包括突显醉酒驾驶的危机性的宣传海报,然后让其中20人玩了10分钟 的《俄罗斯方块》,而另一半人什么也没有做.研究人员发现,玩过游戏的人在接下来的一星期里,伤痛回忆突然重现的情况少得多.

    负责领导这项研究的霍姆斯博士认为,俄罗斯方块有助阻止大脑贮存痛苦回忆,但必须是在事发后马上就玩.

    研究人员解释,这是因为大脑分为两部分:一部分负责感官,另一部分负责分析.由于我们一心二用──例如一边跟人谈话一边解决数学问题──的能力有限,这种计算机游戏可以“干扰大脑保留记忆的方式”.

    研究人员选择《俄罗斯方块》是因为它要求玩家将彩色的方块到处移动,能驱使大部分大脑参与活动.不过,他们不清楚其它计算机游戏是否同样有效.

    霍姆斯说:“《俄罗斯方块》有效可能是因为它争夺大脑争取感官信息的资源.我们发现它明确地干预感官回忆在受到创伤后的时段被贮存下来的方式,从而减少了之后发生的回忆闪现的次数.”

    另一位研究人员指出,事发后的6小时是关键:“以健康的志愿人士来说,在这个时间段内玩《俄罗斯方块》可以减少突现闪现式的回忆,而又不会影响理解那次事件的能力.”

    以下附上HTML的俄罗斯方块源代码,和现在的应用程序比是很简陋的,不过也是很方便的。

    <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
    <html xmlns=”http://www.w3.org/1999/xhtml”>
    <head>
    <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
    <title>俄罗斯方</title>
    </head>

    <body>
    <style>
    span.btn
    {
    BORDER-RIGHT: #7b9ebd 1px solid;
    PADDING-RIGHT: 2px;
    BORDER-TOP: #7b9ebd 1px solid;
    PADDING-LEFT: 2px;
    FONT-SIZE: 12px;
    FILTER: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=#ffffff, EndColorStr=#cecfde);
    BORDER-LEFT: #7b9ebd 1px solid;
    COLOR: black;
    PADDING-TOP: 2px;
    BORDER-BOTTOM: #7b9ebd 1px solid;
    background-color: #CCCCCC;
    }
    </style>
    <script language=”javascript”>
    var doing;
    var candown=0;
    var wnum=13;
    var hnum=18;
    var grid=new Array();
    var gridBuf=new Array();
    for(i=0;i<=hnum;i++){
    grid[i]=new Array();
    gridBuf[i]=new Array();
    for(j=0;j<=wnum;j++){
    if(j>0 && j<wnum && i<hnum){
    grid[i][j]=0;
    gridBuf[i][j]=0;
    }else{
    grid[i][j]=1;
    gridBuf[i][j]=1;
    }
    }
    }

    var boxdata=
    [
    [
    [1,1,1,1],
    [0,0,0,0],
    [0,0,0,0],
    [0,0,0,0]
    ],
    [
    [1,1,1,0],
    [1,0,0,0],
    [0,0,0,0],
    [0,0,0,0],

    ],
    [
    [1,1,1,0],
    [0,1,0,0],
    [0,0,0,0],
    [0,0,0,0]
    ],
    [
    [1,1,1,0],
    [0,0,1,0],
    [0,0,0,0],
    [0,0,0,0]
    ],
    [
    [1,1,0,0],
    [0,1,1,0],
    [0,0,0,0],
    [0,0,0,0]
    ],
    [
    [0,1,1,0],
    [1,1,0,0],
    [0,0,0,0],
    [0,0,0,0]
    ],
    [
    [1,1,0,0],
    [1,1,0,0],
    [0,0,0,0],
    [0,0,0,0]
    ]
    ];

    var colors=[“black”,”#A0A0A0″,”red”,”#FF8000″,”yellow”,”pink”];
    var gotLine=0;
    var box;
    var bGameOver=false;
    function getHeight(arr)
    {
    var i,j;
    for(i=3;i>=0;i–)
    for(j=0;j<4;j++)
    if(arr[i][j]) return i;
    }
    function getWidth(arr)
    {
    var i,j;
    for(i=3;i>=0;i–)
    for(j=0;j<4;j++)
    if(arr[j][i]) return i;
    }

    function Box(x,y,arr,color)
    {
    this.arr=arr;
    this.x=x;
    this.y=y;
    this.w=getWidth(arr);
    this.h=getHeight(arr);
    this.color=color;
    this.active=true;

    this.clearOldBox=function()
    {
    for(var j=0;j<=this.h;j++)
    for(var i=0;i<=this.w;i++)
    if(this.arr[j][i]>0) grid[this.y+j][this.x+i]=0;
    }

    this.putNewBox=function()
    {
    for(var j=0;j<=this.h;j++)
    for(var i=0;i<=this.w;i++)
    if(this.arr[j][i]>0) grid[this.y+j][this.x+i]=this.color;

    }

    this.moveLeft=function()
    {
    this.clearOldBox();
    var _x=this.x-1;
    if(this.canMove(_x,this.y)) this.x=_x;
    this.putNewBox();
    drawGrid();
    }
    this.moveRight=function()
    {
    this.clearOldBox();
    var _x=this.x+1;
    if(this.canMove(_x,this.y)) this.x=_x;
    this.putNewBox();
    drawGrid();
    }

    this.moveDown=function()
    {
    this.clearOldBox();

    var _y=this.y+1;
    if(this.canMove(this.x,_y)){
    this.y=_y;
    this.putNewBox();
    drawGrid();

    }else{
    this.putNewBox();
    drawGrid();
    checkLineFull();
    return;
    }

    }

    this.rotate=function()
    {
    var tmp=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]];
    for(j=0;j<=this.h;j++)
    for(i=0;i<=this.w;i++)
    tmp[this.w-i][j]=this.arr[j][i];
    var newBox=new Box(this.x,this.y,tmp,this.color);
    this.clearOldBox();
    if(! newBox.canMove(this.x,this.y)) this.putNewBox();
    else
    {
    box=newBox;
    box.putNewBox();
    drawGrid();
    }
    }
    this.canMove=function(x,y)
    {
    for(var j=0;j<=this.h;j++)
    for(var i=0;i<=this.w;i++)
    {
    if(grid[y+j][x+i]!=0 && this.arr[j][i]!=0){ candown=1;return false; }
    }
    return true;
    }

    }

    function drawGrid()
    {
    for(var j=0;j<hnum;j++)
    for(var i=0;i<wnum;i++)
    {
    if( grid[j][i]!=gridBuf[j][i])
    {
    paintCell(j,i,grid[j][i]);
    }
    gridBuf[j][i]=grid[j][i];

    }
    }

    function paintCell(i,j,color)
    {
    var htmlGrid=document.getElementById(“TetrisGrid”).firstChild;
    htmlGrid.childNodes[i].childNodes[j].style.backgroundColor=colors[color];

    }
    function init()
    {
    var html='<table id=”TetrisGrid” cellspacing=1 style=”background-color:green”><tbody>’;
    for(var i=0;i<=hnum;i++)
    {
    html+='<tr>’;
    for(var j=0;j<=wnum;j++)
    {

    html+='<td width=”20″ height=”20″ style=”background-color:’+colors[grid[i][j]]+’;”></td>’;
    }
    html+='</tr> \r\n’;
    }
    html+='</tbody></table>’;
    document.write(html);

    }

    function checkLineFull()
    {
    var full,i,j,i2;
    var y3=box.y+box.h;
    var y4=box.y;
    for(i=y3;i>=y4;)
    {
    full=1;
    for(j=0;j<wnum;j++)
    if(grid[i][j]==0){full=0; break;}
    if(full==0){ –i; continue;}
    for(i2=i; i2>0;i2–)
    for(j=0;j<wnum;j++)
    grid[i2][j]=grid[i2-1][j];
    drawGrid();
    y4++;
    gotLine++;
    }
    checkGameOver();
    }

    function checkGameOver()
    {
    var bOver=false;
    for(var j=1;j<wnum;j++)
    if(grid[0][j]>0){ bOver=true; break;}
    if(!bOver){
    box=new Box((wnum-1)/2,0,boxdata[Math.floor(Math.random()*7)],Math.floor(Math.random()*5)+1);
    box.putNewBox();
    }
    else
    {
    bGameOver=true;
    msg.innerHTML=”游戏结束! 您的得分为”+gotLine*100;
    window.clearTimeout(doing);
    }
    }
    function document_onkeydown()
    {
    if(bGameOver) return;
    switch(event.keyCode)
    {
    case 32:
    down();
    break;
    case 37:
    box.moveLeft();
    break;
    case 39:
    box.moveRight();
    break;
    case 38:
    box.rotate();
    break;
    case 40:
    box.moveDown();
    break;
    case 80:
    stop();
    break;
    case 66:
    window.location.reload();
    break;
    case 67:
    restart();
    break;
    }
    }
    function down(){
    if(window.event.keyCode==32){
    clearTimeout(doing);
    for(i=0;i<hnum;i++){
    if(candown==0){
    box.moveDown();
    }else{
    break;
    }
    }
    candown=0;
    doing=window.setTimeout(‘moveDownBox()’,interval);
    }
    }
    var interval;
    function moveDownBox()
    {
    interval=1000-10*(gotLine>80?80 :gotLine);
    msg.innerHTML=” 等级:”+Math.floor(gotLine/10)+”;得分:”+gotLine*100;
    box.moveDown();
    doing=window.setTimeout(‘moveDownBox()’,interval);
    }
    function startGame()
    {
    init();
    doing=window.setTimeout(‘moveDownBox()’,1000);
    bGameOver=false;
    box=new Box((wnum-1)/2,0,boxdata[Math.floor(Math.random()*7)],Math.floor(Math.random()*5)+1);
    box.putNewBox();
    drawGrid();
    }
    var status;
    function stop(){
    status=1;
    window.clearTimeout(doing);
    }
    function restart(){
    if(status==1){
    status=0;
    doing=window.setTimeout(‘moveDownBox()’,1000);
    }
    }
    function keydown(){
    if (document.all)document_onkeydown()
    }
    </script>
    <BODY onLoad=”window.focus()” onkeydown=”keydown()”>
    <table width=”100%” height=”100%” border=”0″ align=”center” cellpadding=”0″ cellspacing=”0″>
    <tr>
    <td>
    <table id=”maintable” border=”0″ align=”center” cellpadding=”0″ cellspacing=”0″>
    <tr>
    <td align=”center”>
    <span class=”btn” style=”width:100%; height:24px;background-color:#F0C0C0;color:#0000FF;vertical-align:middle;text-align:center”>俄罗斯方块</span></td>
    </tr>
    <tr>
    <td style=”height:20px;background-color:black;color:#00FF00;font-size:12px;”><table height=”20″ border=”0″ cellpadding=”0″ cellspacing=”0″>
    <tr style=”font-size:12px; color:#FFFFFF”>
    <td width=”100%”> <a style=”cursor:hand” onclick=”window.location.reload()”>开始(B)</a> <a style=”cursor:hand” onclick=”stop();”>暂停(P)</a> <a style=”cursor:hand” onclick=”restart();”>继续(C)</a></td>
    </tr>
    </table></td>
    </tr>
    <tr>
    <td style=”height:20px;background-color:black;color:#00FF00;font-size:12px;” id=”msg”> 等级:0;得分:0</td>
    </tr>
    <tr>
    <td height=”20″>
    <script language=javascript>
    maintable.style.width=(wnum+1)*20;
    startGame();
    </script>
    </td>
    </tr>
    </table></td>
    </tr>
    </table>
    </body>
    </html>

  • PHP获取网页源代码内容

    php可以用几个函数来采集网页的源代码,晚上无聊写了一份查看搜索引擎收录情况的代码,只是简单写了下并没有做什么处理,把代码贴上面留日后查看。
     function baidu($s,$t){
     $baidu=”http://www.baidu.com/s?wd=site%3A”.$s.”&lm=”.$t;
     $site=file_get_contents($baidu);
     $site=iconv(“gb2312”, “UTF-8”, $site);
     ereg(“相关网页(.*)篇”, $site, $count);
     $count=str_replace(“相关网页”,””,$count);
     $count=str_replace(“篇”,””,$count);
     $count=str_replace(“约”,””,$count);
     return $count[0];
     } 
     function google($s,$t){
     $google=”http://www.google.cn/search?q=site%3A”.$s.”&as_qdr=”.$t;
     $site=file_get_contents($google);
     $site=iconv(“gb2312”, “UTF-8”, $site);
     ereg(“约有 <b>(.*)</b> 项符合”, $site, $count);
     $count=str_replace(“约有 <b>”,””,$count);
     $count=str_replace(“</b> 项符合”,””,$count);
     return $count[0];
     }

  • .me域名查询地址

    官方的地址发一下 之前找了很久没找到的。
    http://www.domain.me/

  • 网页版贪吃蛇

      功能:蛇吃食物有四种情况:走到的地方有食物;走到的地方没有食物;走到的地方是墙壁;走到的地方是自己的身体。吃到食物后,蛇的身体会变长;碰到墙壁或咬到自己 Game Over,询问是否重新开始。

        整个游戏是在一个<div>框子(地图)里展开的,蛇有地图里的一系列<div>构成,初始状态(刚刚打开页面)蛇是一个<div>框,蛇头和蛇尾是在一起的,就是这个<div>框,以后吃了食物后<div>个数会变多,蛇就会长长。食物用一个<span>框表示,初始时和蛇一样其位置是随机产生的。蛇和食物的坐标用<div>和<span>的绝对位置表示。

        算法的关键是当蛇移动到新的位置后,判断前述的几种情况,做出相应的处理。而二维数组 Map[][] 就是判断的依据。二维数组 Map[][]通过其元素的值来表示蛇身、食物和空地。蛇身、食物和空地的值分别为’S’、’F’ 和 ‘0′。

        用 Javascript 编程和其他语言的一个大的区别就是键盘的控制代码不同。js是通过 Key=event.keyCode 语句获取键盘码,再在多分支 switch 结构里分别处理。看完这些代码就会对浏览器里的键盘控制有所了解了。

        当然该段代码的最大价值还是让我们了解到网页游戏的大概写法,而算法其实是最重要的,把一个游戏的设想变为一堆包含许多的函数的结构化的代码,是值得我们借鉴和学习的。这里的难点是确定蛇是怎么移动的。

        代码里有我的注释,结合我的以上大概分析介绍差不多能看懂了。

        题外问题:

        本人在调试的时候打算给原来的代码加一段地图内方格显示功能,就写了个ShowGrid()函数,采用代码生成方格。但由于在2层循环内完成方格显示,效率十分低下,生成15*10的方格需要大约6秒。生成30*20 的方格竟然需要几分钟。基本不能采用此方法。改进以后,不是生成多个包含单个单元格的表格,而是生成一个包含若干单元格的表格,结果效率有巨大的提高。

        改进后,有如下功能:
        – 可改变单元格数;
        – 可控制暂停;
        – 速度控制功能;
        – 蛇头、蛇身和蛇尾形状美化;
        – 可控制显示和隐藏背景图片、方格线;
        – 修正了长度等于或大于2节的蛇体,按倒退键时结束游戏的错误;

        进一步改进建议:
        – 控制蛇头的方向,可用动画图片代替蛇头。
        – 蛇身和蛇尾也可用图片代替。
        – 增加声音;
        – 增加换肤功能:背景、方格、蛇的皮肤可定制;
        – 自动演示功能;
        ……

    <HTML>
    <head>
    <meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″>
    <title>贪吃蛇</title>
    <style>
      body{font-size: 12px;}

      .food
      {
        background: url(”images/food1.gif”) no-repeat;
        /*background-color:green;*/
        overflow:hidden;
        position:absolute;
      }

      .snake_head
      {
        background-color: red;
        border:3px solid gold;
        position:absolute;
      }

      .snake_body
      {
        background-color: orange;
        border:2px dotted white;
        position:absolute;
      }

      .snake_tail
      {
        background-color: peachpuff;
        border:2px dotted white;
        position:absolute;
      }

      .grid
      {
        border-style:solid;
        border-color:#0000ff;
        border-top-width:0;
        border-right-width:1;
        border-bottom-width:1;
        border-left-width:0;
        padding:0;
      }

      .mainmap
      {
        position:absolute;
        border-style:outset;
        border-color:#0000ff;
        border-width:5;
      }

      .table
      {
        position:absolute;
        overflow:hidden;
        border-collapse:collapse;
      }
    </style>
    </head>

    <BODY>
    <div id=”help”>
      红色方块表示蛇头,按方向键控制蛇吃食物<br><br>
      行数:
      <select id=”rows”>
        <option>25</option>
        <script language=”javascript”>
          for(var ct=10;ct<=30;ct++)
            document.write(’<option>’ + ct + ‘</option>’);
        </script>
      </select>
      <br>
      列数:
      <select id=”cells”>
        <option>30</option>
        <script language=”javascript”>
          for(var ct=10;ct<=40;ct++)
            document.write(’<option>’ + ct + ‘</option>’);
        </script>
      </select>
      <br>
      <button onclick=”reCreateMap()”> 设置 </button>
      <br><br>
      【初始化:】F5 功能键<br>
      【暂停:】S 字母键<br><br>
      【显示/隐藏网格:】G 字母键<br><br>
      【加速:】PageUP 键<br>
      【减速:】PageDown 键<br>
    </div>
    【速度:】<span id=”speed” style=”color:red”></span>

    <br><br><div id=”mapxy”></div>
    <div
      <br><br>
      蛇只能吃食物,<br>不能触墙,<br>也不能咬自己
    </div>

    <script langyage=”javascript”>
      var Rows = document.getElementById(’rows’).options[0].text;
      var Cells = document.getElementById(’cells’).options[0].text;
      var Num   = 20;  //正方形格子的边长
      var SpeedUp = 5000;
      var Times = 200;
      var Start = 0;
      var ShowGrid = true;
      var ShowBackground  = true;

      var BorderWidth = 5;
      var MainMap = null;
      var AllDiv  = new Array();
      var AllSpan = new Array();
      var Sx = Sy = 0;
      var Map = null;
      var GoX,GoY,LastX,LastY;
      var moving = null;
      var AllDiv=null, AllSpan=null;

      //重新创建地图
      function reCreateMap()
      {
        Rows = document.getElementById(’rows’).options[document.getElementById(’rows’).selectedIndex].text;
        Cells = document.getElementById(’cells’).options[document.getElementById(’cells’).selectedIndex].text;
        document.body.removeChild(MainMap);
        CreateMap();
      }

      //创建地图
      function CreateMap()
      {
        BW = eval(Cells * Num + 2 * BorderWidth);  //宽度
        BH = eval(Rows * Num + 2 * BorderWidth);   //高度
        //document.body.innerHTML+=’<div id=MainMap style=position:absolute;left:’+(document.body.clientWidth-BW)/2+’;top:’+(document.body.clientHeight-BH)/2+’;width:’+BW+’;height:’+BH+’;border-width:’+BorderWidth+’;></div>’
        MainMap = document.createElement(’div’);
        MainMap.className = ‘mainmap’;
        if(ShowBackground)
          MainMap.style.backgroundImage = “url(’images/bgpic.jpg’)”;
        MainMap.style.left = (document.body.clientWidth – BW) / 2;
        MainMap.style.top  = (document.body.clientHeight – BH) / 2;
        MainMap.style.width  = BW;
        MainMap.style.height = BH;
        document.body.appendChild(MainMap);

        //创建全局数组Map[]
        /*
        Map = new Array() //创建全局数组Map[]
        for(y=0; y<Rows; y++)
        {
          Map[y]=new Array() //创建全局二维数组Map[][],初始值为’0′
          for(x=0; x<Cells; x++)
            Map[y][x] = ‘0′  //’0′值表示“空地”
        }
        */
        Map = new Array();
        for(y = 0; y < Rows; y++)
        {
          //创建全局二维数组Map[][],初始值为’0′
          Map.push(new Array());
          for( x = 0; x < Cells; x++)
            Map[y].push(’0′);  //’0′值表示“空地”
        }
        //显示地图内格子
        if (ShowGrid)
          MainMap.appendChild(CreateGrid(’ ‘));

        //创建全局变量Sx,赋予随机数
        Sx = parseInt(Math.random() * Cells);

        //创建全局变量Sy,赋予随机数
        Sy = parseInt(Math.random() * Rows);

        //生成蛇 – div
        CreateSnake();

        //生成食物 – span
        CreatFood();

        //创建全局数组AllDiv,保存着蛇身各节<div>。AllDiv[0]为蛇尾。MainMap是div的ID
        AllDiv  = MainMap.getElementsByTagName(’div’);  //等价于AllDiv = MainMap.all.tags(’DIV’)
        //创建全局数组AllSpan,始终只有一个元素AllSpan[0]
        AllSpan = MainMap.getElementsByTagName(’span’);  //等价于AllSpan = MainMap.all.tags(’SPAN’)
      }

      //创建地图内格子(Rows*Cells 大小的 Table)
      function CreateGrid(celltext)
      {
        var table = document.createElement(’table’);
        table.className = ‘table’;
        table.style.left  = 0;
        table.style.top  = 0;
        table.setAttribute(’id’,’grid’);
        table.setAttribute(’border’,’0′);  //table.border = ‘0′;
        table.setAttribute(’cellspacing’,’0′);
        table.setAttribute(’cellpadding’,’0′);
        var tbody = document.createElement(”tbody”);
        table.insertBefore(tbody, null);
        for (var i=0; i<Rows; i++)
        {
          var tr = document.createElement(’tr’);
          for(var j=0; j<Cells; j++)
          {
            var td = document.createElement(’td’);
            td.className = ‘grid’;
            td.width  = Num;  //td.style.width  = Num;
            td.height  = Num;  //td.style.height  = Num;
            var text = document.createTextNode(celltext);
            td.insertBefore(text, null);
            tr.insertBefore(td, null);
          }
          tbody.insertBefore(tr, null);
        }
        return table;
      }

      //创建蛇的位置,赋予值’S’
      function CreateSnake()
      {
        //<div>表示蛇身,通过调用本函数,可以累加到若干个,蛇身变长
        //注意 y 和 x 是“蛇”<div> 的自定义属性。一直保存着蛇身体各节的Map坐标,与Map[][]联系
        //初始时,蛇头、蛇尾是同一个位置
        var div = document.createElement(’div’);
        div.className = ’snake_head’;
        div.setAttribute(’x’,Sx);
        div.setAttribute(’y’,Sy);
        div.style.left = Sx * Num;
        div.style.top  = Sy * Num;
        div.style.width  = Num;
        div.style.height = Num;
        MainMap.appendChild(div);

        Map[Sy][Sx] = ‘S’;  //Snake首字母

        //蛇身长度
        //document.all.mapxy.innerHTML = AllDiv.length;
        if (AllDiv!=null)
        {
          if (AllDiv.length>1)
          {
            AllDiv[0].className = ’snake_tail’; //蛇尾
            for (var i=1;i<AllDiv.length-1;i++) //蛇身
              AllDiv[i].className = ’snake_body’;
          }
        }
      }

      //创建食物的位置,赋予初始值’F’
      //食物的初始位置不能与蛇的初始位置相同,只能在空地放置食物。
      //若随机产生的2位置相同,则递归执行,直到不相同为止
      function CreatFood()
      {
        Fx = parseInt(Math.random() * Cells);
        Fy = parseInt(Math.random() * Rows);
        if(Map[Fy][Fx] == ‘0′)  //如果是空地
        {
          MainMap.appendChild(CreatSpan(Fx * Num,Fy * Num,Num));
          Map[Fy][Fx] = ‘F’;  //Food首字母
        }
        else
        {
          CreatFood(); //递归
        }
      }

      //生成食物的span
      function CreatSpan(l,t,num)
      {
        var span = document.createElement(’span’);
        span.style.left = l;
        span.style.top  = t;
        span.style.width  = num;
        span.style.height = num;
        span.className = ‘food’;
        return span;
      }

      //主移动–判断蛇头前面的是什么
      function Move()
      {
        //自动行走,Map[Sy][Sx]为蛇头前面位置
        Sx += GoX;
        Sy += GoY;

        //碰墙,重新开始
        if(Sy < 0 || Sy >= Rows)
        {
          Move1();
        }
        else
        {
          SnakeFront = Map[Sy][Sx];
          switch(SnakeFront)
          {
            case ‘0′:  //蛇前是空地
              Move2();
              break;
            case ‘F’:  //蛇前面是食物
              Move3();
              break;
            case ‘S’:  //蛇前面是自己的身体
              Move1();
              break;
            default:  //啥都不是就是超出地图范围game over
              Move1();
          }
        }
      }

      //重新开始
      function Move1()
      {
        if(confirm(”Game Over,重新开始?”))
        {
          //window.location.reload();
          reCreateMap();
          Start = 0;
        }
        else
          window.close();
      }

      //蛇行走到的当前位置是空地时
      function Move2()
      {
        //蛇走开后,把原位置设置为’0′,表示是空地
        //把蛇数组当前元素删除,在下面的 CreateSnake()语句重新生成
        Map[AllDiv[0].getAttribute(’y’)][AllDiv[0].getAttribute(’x’)] = ‘0′;
        var fatherNode = AllDiv[0].parentNode;  //AllDiv[0].removeNode(true);
        fatherNode.removeChild(AllDiv[0]);

        //在新的位置生成蛇的<div>
        CreateSnake();
        //再次移动
        moving = setTimeout(’Move()’,Times);
      }

      //蛇行走到的当前位置是食物时
      function Move3()
      {
        //蛇数组当前元素不删除,<div>累加一次,蛇长长一节
        CreateSnake();
        //把食物数组当前元素删除,在下面的 CreatFood()语句重新生成
        var parentNode = AllSpan[0].parentNode;  //AllSpan[0].removeNode(true)
        parentNode.removeChild(AllSpan[0]);
        //再次随机生成食物
        CreatFood();
        //再次移动
        moving = setTimeout(’Move()’,Times);
      }

      //蛇行加速
      function oTimes(step)
      {
        if(step>0 && Times>30)
          Times -= step;
        if(step<0 && Times<400)
          Times -= step;
        document.getElementById(’speed’).innerHTML = Times;
        //If(Times > 5) setTimeout(’oTimes()’, SpeedUp);
      }

      //绑定键盘事件
      document.onkeydown = KeyDown;

      //按键
      function KeyDown(e)
      {
        if(e)
          Key = e.keyCode;
        else
          Key = window.event.keyCode
        switch(Key)
        {
          case 37: //左方向键
            Dir(-1,0);
            break
          case 39: //右方向键
            Dir(1,0);
            break
          case 38: //上方向键
            Dir(0,-1);
            break
          case 40: //下方向键
            Dir(0,1);
            break
        case 33: //PageUp – speed up
            oTimes(5);
         break;
        case 34: //PageDown – speed down
            oTimes(-5);
         break;
        case 66: // B – Show/Hidden Background
          ShowBackground = !ShowBackground;
          if(ShowBackground)
          {
            MainMap.style.backgroundImage = “url(’images/bgpic.jpg’)”;
            //MainMap.style.backgroundRepeat=”repeat-x repeat-y”;
            //MainMap.style.backgroundRepeat=”no-repeat”;
          }
          else
            MainMap.style.backgroundImage = “url(”)”;
         break;
        case 71: // G – Show/Hidden Grid
          ShowGrid = !ShowGrid;
          if(ShowGrid)
            MainMap.appendChild(CreateGrid(’ ‘));
          else
              MainMap.removeChild(document.getElementById(’grid’));
         break;
        case 83: // s – stop
         clearTimeout(moving);
         Start = 0;
         break;
        }
        return false
      }

      function Dir(x,y)
      {
        GoX = x;
        GoY = y;
        if( Start == 0 )
        {
          LastX = x;
          LastY = y;
          clearTimeout(moving);
          Start = 1;
          Move();
        }
        else
        {
          /* 增加的反方向判断 */
          //检查上次行动方向和本次行动方向,如果方向正好相反那么还是保持上次的前进方向
          if (GoX + LastX == 0 && GoY + LastY == 0)
          {
            GoX = LastX;
            GoY = LastY;
          }
          else
          { //如果不一样则记住本次的行动方向
            LastX = GoX;
            LastY = GoY;
          }
        }
      }

      //绘制地图
      CreateMap();
      document.getElementById(’speed’).innerHTML = Times;
    </script>
    </BODY>
    </HTML>