Oct
07
Posted (xurenlu) in 未分类 on 10月-7-2007

之前做过一个测试:
select id,title from ** 与select * from **的速度测试。
这是后续版.

  1. <?php
  2. define("TIMES",10000);
  3. $SQL1="SELECT * FROM stat_visits";
  4. $SQL2="SELECT v_id,v_url,v_site_id,v_screen_size,v_h,v_m,v_s,v_flash,v_director,
  5. v_quicktime,v_realplayer,v_pdf,v_windowsmedia,v_java,v_cookie,v_ref,v_remote_ip,
  6. v_timezone,v_color_depth,v_type,v_year,v_month,v_day,v_time FROM stat_visits";
  7. $conn=mysql_connect("localhost","root","");
  8. mysql_select_db("test");
  9. $time1=array_sum(explode(' ', microtime()));
  10. for($i=0;$i<times;$i++)
  11. </times;$i++)
  12.   mysql_query($SQL1);
  13. $time2=array_sum(explode(' ', microtime()));
  14. for($i=0;$i<times;$i++)
  15. </times;$i++)
  16.   mysql_query($SQL2);
  17. $time3=array_sum(explode(' ', microtime()));
  18.  
  19. $cost1=$time2-$time1;
  20. $cost2=$time3-$time2;
  21. print "cost1:$cost1\n";
  22. print "cost2:$cost2\n";
  23.  
  24. ?>

测试的结果是:

  1. [st@localhost test]$ php select.php
  2. cost1:2.1355810165405
  3. cost2:2.5820469856262
  4. [st@localhost test]$ php select.php
  5. cost1:1.9796178340912
  6. cost2:2.5190000534058
  7. [st@localhost test]$ php select.php
  8. cost1:1.9672379493713
  9. cost2:2.9030020236969
  10. [st@localhost test]$ php select.php
  11. cost1:1.9810240268707
  12. cost2:2.5505940914154

好了,现在将SQL1和SQL2次序交换:

  1. calhost test]$ php select.php
  2. cost1:2.5933158397675
  3. cost2:2.0362050533295
  4. [st@localhost test]$ php select.php
  5. cost1:2.6104090213776
  6. cost2:2.056037902832
  7. [st@localhost test]$ php select.php
  8. cost1:4.2802629470825
  9. cost2:3.3958988189697
  10. [st@localhost test]$ php select.php
  11. cost1:2.6283531188965
  12. cost2:2.0102050304413

大体上,SELECT COL1,COL2,COL3….. 与SELECT * 相比,两者花费的时间之比是4:5.不知道非空表的结果会不会是这样?


Tag:
相关文章


     
    Oct
    07
    Posted (xurenlu) in 未分类 on 10月-7-2007

    这两天觉得自己的基本功不够扎实,于是躲在家里看PHP,mysql手册。
    发现这个句子在大部分情况下能实现随机读取mysql记录:
    表的结构如下:

    1. | id             | bigint(11) unsigned | NO   | PRI | NULL    | auto_increment |
    2. | tag            | varchar(32)         | NO   |     |         |                |
    3. | hash           | varchar(32)         | NO   |     |         |                |
    4. | created        | bigint(11)          | NO   |     |         |                |
    5. | article_id     | bigint(11)          | NO   |     |         |                |
    1. select * from tag order by RAND() desc limit 10\G

    秘决在于:
    1.Rand函数.
    2.不仅用order by id可以依id排序,用order by 1也可以依id排序.因此用rand函数来生成order by 子句。

    犯错误了,order by 1 确实可以生效,但是rand函数不能用在order by 子句中。 而且,当表中有column(1),column(2)…..共10列时,用order by 1,order by 2,….分别是按column(1),column(2)…排序的,但是我用order by 11时,就报错了。再用SELECT * FROM table order by RAND()*1000,却不报错。

    看下面的例子:

    1. select *,(rand()*1000) as a from x_feeds order by a;

    每次输出,都不同。
    再稍变一次:

    1. mysql&gt;select *,(rand()*1000) as a from x_feeds order by 514;

    每次都出错。
    再变之:

    1. mysql&gt;select *,(rand()*1000) as a from x_feeds order by 514.37134

    将order by 后跟上小数(学计算机的不能这么说啊),就能正常输出,但是是按表的原来顺序输出的,每次结果都一样。
    暂时未找到真正原因,mysql文档中文版如此说:

    你不能在一个ORDER BY子句用RAND()值使用列,因为ORDER BY将重复计算列多次。然而在MySQL3.23中,你可以做: SELECT * FROM table_name ORDER BY RAND(),这是有利于得到一个来自SELECT * FROM table1,table2 WHERE a=b AND c<d ORDER BY RAND() LIMIT 1000的集合的随机样本。注意在一个WHERE子句里的一个RAND()将在每次WHERE被执行时重新评估。


    Tag:
    相关文章


       
      Aug
      21
      Posted (xurenlu) in php性能, php技术 on 08月-21-2007

      我的师兄,从某种程度上说也是我php方面的师父,和他的同事做了测评,分别是针对php4,php5的性能对比和function,class的性能对比的。
      这里是师兄的对比结果
      师兄的同事做的测评
      但是我不认为用ab来做出的测试是合理的.理由:用ab来测试时,结果好像总似是在跳舞一样.做为证据,我将我的notebook依文本方式重启,用ab来测lighttpd的表现.
      具体环境:
      Haier H40S Notebook
      RAM:1.5G
      CPU:CY 1.6GHz
      硬盘:60G,(具体型号什么的不清楚,列个60G表示不是SCSI硬盘)
      OS:Fedora Core 7.0(Moonshine)
      web server:lighttpd 1.4.15
      测试工具:ab
      X环境:未运行X server
      命令:ab -n 10000 -c 50 http://localhost:8181/
      第一份结果:

      1. This is ApacheBench, Version 2.0.40-dev &lt;$Revision: 1.146 $&gt; apache-2.0
      2. Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
      3. Copyright 2006 The Apache Software Foundation, http://www.apache.org/

      Benchmarking localhost (be patient)

      Server Software: lighttpd/1.4.15
      Server Hostname: localhost
      Server Port: 8181

      Document Path: /
      Document Length: 345 bytes

      Concurrency Level: 50
      Time taken for tests: 1.786830 seconds
      Complete requests: 10000
      Failed requests: 0
      Write errors: 0
      Non-2xx responses: 10000
      Total transferred: 4980000 bytes
      HTML transferred: 3450000 bytes
      Requests per second: 5596.50 [#/sec] (mean)
      Time per request: 8.934 [ms] (mean)
      Time per request: 0.179 [ms] (mean, across all concurrent requests)
      Transfer rate: 2721.58 [Kbytes/sec] received

      Connection Times (ms)
      min mean[+/-sd] median max
      Connect: 0 3 2.6 4 8
      Processing: 1 4 0.7 5 6
      Waiting: 0 1 1.7 2 5
      Total: 5 8 2.2 8 13
      WARNING: The median and mean for the processing time are not within a normal deviation
      These results are probably not that reliable.

      Percentage of the requests served within a certain time (ms)
      50% 8
      66% 10
      75% 10
      80% 11
      90% 11
      95% 12
      98% 12
      99% 12
      100% 13 (longest request)

      这里的结果是Requests per second: 5596.50 [#/sec] (mean)(插一句,lighttpd的性能真是好,用apache从来没上过3000)
      第二份ab -n 10000 -c 50的结果:

      1. This is ApacheBench, Version 2.0.40-dev &lt;$Revision: 1.146 $&gt; apache-2.0
      2. Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
      3. Copyright 2006 The Apache Software Foundation, http://www.apache.org/

      Benchmarking localhost (be patient)

      Server Software: lighttpd/1.4.15
      Server Hostname: localhost
      Server Port: 8181

      Document Path: /
      Document Length: 345 bytes

      Concurrency Level: 50
      Time taken for tests: 1.313719 seconds
      Complete requests: 10000
      Failed requests: 0
      Write errors: 0
      Non-2xx responses: 10011
      Total transferred: 4985478 bytes
      HTML transferred: 3453795 bytes
      Requests per second: 7611.98 [#/sec] (mean)
      Time per request: 6.569 [ms] (mean)
      Time per request: 0.131 [ms] (mean, across all concurrent requests)
      Transfer rate: 3705.51 [Kbytes/sec] received

      Connection Times (ms)
      min mean[+/-sd] median max
      Connect: 0 1 1.0 1 5
      Processing: 1 5 2.0 5 32
      Waiting: 0 3 1.8 3 30
      Total: 1 6 2.1 6 35

      Percentage of the requests served within a certain time (ms)
      50% 6
      66% 6
      75% 6
      80% 6
      90% 7
      95% 8
      98% 10
      99% 11
      100% 35 (longest request)

      结果表明RPS是Requests per second: 7611.98 [#/sec] (mean).
      第三份结果:

      1. This is ApacheBench, Version 2.0.40-dev &lt;$Revision: 1.146 $&gt; apache-2.0
      2. Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
      3. Copyright 2006 The Apache Software Foundation, http://www.apache.org/

      Benchmarking localhost (be patient)

      Server Software: lighttpd/1.4.15
      Server Hostname: localhost
      Server Port: 8181

      Document Path: /
      Document Length: 345 bytes

      Concurrency Level: 50
      Time taken for tests: 1.300247 seconds
      Complete requests: 10000
      Failed requests: 0
      Write errors: 0
      Non-2xx responses: 10009
      Total transferred: 4984482 bytes
      HTML transferred: 3453105 bytes
      Requests per second: 7690.85 [#/sec] (mean)
      Time per request: 6.501 [ms] (mean)
      Time per request: 0.130 [ms] (mean, across all concurrent requests)
      Transfer rate: 3743.14 [Kbytes/sec] received

      Connection Times (ms)
      min mean[+/-sd] median max
      Connect: 0 1 1.0 1 5
      Processing: 1 4 1.4 5 11
      Waiting: 0 2 1.1 3 8
      Total: 1 6 1.2 6 14

      Percentage of the requests served within a certain time (ms)
      50% 6
      66% 6
      75% 6
      80% 6
      90% 7
      95% 9
      98% 10
      99% 11
      100% 14 (longest request)

      RPS结果是Requests per second: 7690.85 [#/sec] (mean).
      第四份结果是:

      1. This is ApacheBench, Version 2.0.40-dev &lt;$Revision: 1.146 $&gt; apache-2.0
      2. Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
      3. Copyright 2006 The Apache Software Foundation, http://www.apache.org/

      Benchmarking localhost (be patient)

      Server Software: lighttpd/1.4.15
      Server Hostname: localhost
      Server Port: 8181

      Document Path: /
      Document Length: 345 bytes

      Concurrency Level: 50
      Time taken for tests: 1.315784 seconds
      Complete requests: 10000
      Failed requests: 0
      Write errors: 0
      Non-2xx responses: 10033
      Total transferred: 4996434 bytes
      HTML transferred: 3461385 bytes
      Requests per second: 7600.03 [#/sec] (mean)
      Time per request: 6.579 [ms] (mean)
      Time per request: 0.132 [ms] (mean, across all concurrent requests)
      Transfer rate: 3708.06 [Kbytes/sec] received

      Connection Times (ms)
      min mean[+/-sd] median max
      Connect: 0 1 1.2 1 8
      Processing: 1 4 1.4 5 11
      Waiting: 0 2 1.1 3 8
      Total: 1 6 1.4 6 15

      Percentage of the requests served within a certain time (ms)
      50% 6
      66% 6
      75% 6
      80% 6
      90% 7
      95% 9
      98% 11
      99% 12
      100% 15 (longest request)

      结果是Requests per second: 7600.03 [#/sec] (mean).
      第五份结果是:

      1. This is ApacheBench, Version 2.0.40-dev &lt;$Revision: 1.146 $&gt; apache-2.0
      2. Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
      3. Copyright 2006 The Apache Software Foundation, http://www.apache.org/

      Benchmarking localhost (be patient)

      Server Software: lighttpd/1.4.15
      Server Hostname: localhost
      Server Port: 8181

      Document Path: /
      Document Length: 345 bytes

      Concurrency Level: 50
      Time taken for tests: 1.812989 seconds
      Complete requests: 10000
      Failed requests: 0
      Write errors: 0
      Non-2xx responses: 10000
      Total transferred: 4980000 bytes
      HTML transferred: 3450000 bytes
      Requests per second: 5515.75 [#/sec] (mean)
      Time per request: 9.065 [ms] (mean)
      Time per request: 0.181 [ms] (mean, across all concurrent requests)
      Transfer rate: 2682.31 [Kbytes/sec] received

      Connection Times (ms)
      min mean[+/-sd] median max
      Connect: 0 3 2.7 4 9
      Processing: 1 4 0.8 5 6
      Waiting: 0 1 1.7 2 5
      Total: 5 8 2.3 9 13
      WARNING: The median and mean for the processing time are not within a normal deviation
      These results are probably not that reliable.

      Percentage of the requests served within a certain time (ms)
      50% 9
      66% 10
      75% 10
      80% 11
      90% 12
      95% 12
      98% 12
      99% 12
      100% 13 (longest request)

      RPS结果是Requests per second: 5515.75 [#/sec] (mean);

      可以看到,同是ab -n 10000 -c 50 http://localhost:8181/,结果大不一样,不仅分为7600RPS和5500RPS两档,而各档中具体数据也不一样.这个结果可以理解,OS中总是会有各种各样的消息要处理,影响具体数据结果也很正常.
      因此,谢华亮(sir?mm?)的测试用ab的结果来进行php4,php5的性能比较是不太对的.至少目前看来,我没有从他的文章中看到他进行了多次ab测评后取结果的平均值.但是他列出来这样一个结果:

      1. 版本 函数测试 不实例化类 实例化类 类的继承
      2. PHP 4.4.2 1047.23/rps 1034.98/rps 1006.14/rps 992.95/rps
      3. PHP 5.2.1 1176.06/rps 1197.17/rps 1187.93/rps 1128.54/rps

      这大致可以说明,php5.2确实是比php4.4.2要快.但是从1197.17>1176.06得出php5的类跑得比functiong还快,我不这么认为.只是21个request的差别,太小了,ab测试的随便一个风吹草吹就行了(而且说class比function要快,严重地伤害了我的感情,哈哈)…
      嗯,先整这么多.有空好好研究一下,如何对web程序进行性能测评.
      另外,有空见到这两位兄台,好好争论一番.


      Tag:
      相关文章


         
        Aug
        21
        Posted (xurenlu) in 未分类 on 08月-21-2007

        我又写了一个文件.再测之:

        1. <?php
        2.  
        3. function signin()
        4. {
        5. return "null";
        6. }
        7. class User
        8. {
        9.     public function signin()
        10.     {
        11. return "null";
        12.     }
        13.  
        14. }
        15. function time1()
        16. {
        17. $arr=split(" ",microtime());
        18. return $arr[1]+$arr[0];
        19. }
        20. $t1= time1();
        21. for($i=0;$i<100000;$i++)
        22. signin();
        23. $t2=time1();
        24.  
        25. for($i=0;$i<100000;$i++)
        26. User::signin();
        27. $t3=time1();
        28.  
        29. echo "
        30. function:".($t2-$t1)."ms
        31. class:".($t3-$t2)."ms";

        这是结果:

        1. function:0.071924924850464ms
        2. class:0.23149108886719ms

        为了避免程序运行顺序的影响,我们再运行一次,这次先测静态类的,再测function的:

        1. <?php
        2.  
        3. function signin()
        4. {
        5. return "null";
        6. }
        7. class User
        8. {
        9.     public function signin()
        10.     {
        11. return "null";
        12.     }
        13.  
        14. }
        15. function time1()
        16. {
        17. $arr=split(" ",microtime());
        18. return $arr[1]+$arr[0];
        19. }
        20. $t1= time1();
        21.  
        22. for($i=0;$i<100000;$i++)
        23. User::signin();
        24. $t2=time1();
        25.  
        26. for($i=0;$i<100000;$i++)
        27. signin();
        28. $t3=time1();
        29.  
        30. echo "
        31. function:".($t3-$t2)."ms
        32. class:".($t2-$t1)."ms";

        这次测的时间如下:

        1. function:0.072422027587891ms
        2. class:0.26213884353638ms

        从这个结果来看,php的function还是相当快的,比class,哪怕是静态方法要快。
        看来我越来越喜欢用function的路子是对的。

        后来我加上另一个,把整个结果贴出来:

        1. $obj=& new User();
        2.  
        3. $t1= time1();
        4.  
        5. for($i=0;$i<100000;$i++)
        6. User::signin();
        7. $t2=time1();
        8.  
        9. for($i=0;$i<100000;$i++)
        10. signin();
        11. $t3=time1();
        12.  
        13. for($i=0;$i<100000;$i++)
        14. $obj->signin();
        15. $t4=time1();
        16.  
        17. for($i=0;$i<100000;$i++)
        18. {
        19. $obj1=& new User();
        20. $obj1->signin();
        21. }
        22. $t5=time1();
        23. echo "
        24. function:".($t3-$t2)."ms
        25. class:".($t2-$t1)."ms
        26. object:".($t4-$t3)."ms
        27. new object:".($t5-$t4)."ms";

        结果是:

        1. function:0.071459054946899ms
        2. class:0.23710894584656ms
        3. object:0.08794093132019ms
        4. new object:0.17567801475525ms

        也就是说,直接调用function是最快的,其次是重复调用已存在对象的方法,仅比纯function慢一点点。
        接着是先新建class的实例再调用方法,最慢的是直接调用静态方法。
        这个结果有一点点出乎我的意料,我没料到静态方法是最慢的一个。


        Tag:
        相关文章


           
          Aug
          21
          Posted (xurenlu) in php性能 on 08月-21-2007

          老覃同学做了一个测试,来比较PHP5下利用function,class来编程时的效率差异。
          我一向喜欢钻牛角尖:
          有两个疑问:
          1.ab本身的文档说了,ab自身是需要CPU资源的,有时候要注意你可能不是在测apache的性能,而是在测ab这个软件的性能。老覃同志如何去除ab的影响?
          2.php编译时也是花费CPU时间的。我做了另一组测试:

          1. //t1.php

          function signin()

          {

          echo “signin”;

          }

          signin();

          ?>

          ab -n 10000 -c 50 的结果是:
          1534.15 [#/sec]
          Time per request: 32.591 [ms] (mean)

          ,再另外一个:

          function signin()

          {

          echo “signin”;

          }

          //signin();

          ?>

          ab -n 10000 -c 50的结果是:
          1748.48 [#/sec], Time per request: 28.596 。
          就是说,算上ab的花费,apache的花费,php编译的花费,这几个的时间消费可能已经比php代码运行的时间花费要大了。加上运行的代码后,只相关几个ms。
          如果要进行精确的比较,老覃的做法可能很不可靠。
          PHP4与PHP5.20的效率目前还只有看官方的数据。
          另外有个疑问,我的php比老覃同志的似乎快了不少,相差好几倍。可能是我的是Fedora 下运行的结果。

          附注:

          我后来做了一个实验,ab -n 10000 -c 50 http://localhost/test/23442.php ,返回的结果是:

          1. Requests per second:    2192.03 [#/sec] (mean)
          2. Time per request:       22.810 [ms] (mean)

          这是在请求的文件不存在下,apache简单返回一个静态面的情况下的。由此看来,ab和apache的开销就已经占了大约20ms.

          再注,在这里
          是老覃的同事做的测试.我google得到了这个结果.


          Tag:
          相关文章


             
            Aug
            15
            Posted (xurenlu) in php性能 on 08月-15-2007

            两段代码,都是用来1到100之前计算三次方的.
            同样的代码,第一个其实只需要一行(当然要考虑美观,分成了四行);
            第二个估计要用上100来行;但是哪个更快呢?….
            读者说哪个程序更好?

            1.  

            function getPower($n)
            {
            return $n*$n*$n;
            }

            global $data;
            $data=array(
            1=>1,
            2=>8,
            3=>27,
            4=>64,
            5=>125…
            );
            function getPower($n)
            {
            global $n;
            return $data[$n];
            }


            Tag:
            相关文章


               
              Aug
              13
              Posted (xurenlu) in php性能 on 08月-13-2007

              phpfox是国外的一款社区软件,具有论坛,博客,相册,音乐,投票,问答,视频等功能,基于php,mysql.安装需要gd库的支持。

              我拿到程序后修改的第一步:

              1.修改用户接口部分。 phpfox是典型的单入口型程序和类MVC架构。具体怎么改我不加描述了,只提一下,因为phpfox把对几乎所有路径的访问全部rewrite到了index.php,所以要在.htaccess文件中加上这样的两行:

              1. Rewritecond %{REQUEST_FILENAME} !-f
              2. Rewritecond %{REQUEST_FILENAME} !-d

              一共要加两次(针对1.5,1.6这两个版本)。如果没有启用rewrite,就没有这会事。用户分别是{PREFIX}_user表,如果自行进行数据整合,操作这个表就可以了。
              2.汉字在显示时有问题,需要看以下这些模板:

              design/./templates/default/_modules/Menu/TabbedMenu.html
              design/./templates/default/_modules/Listing/ListingCreate.html
              design/./templates/default/_modules/Listing/ListingCreate.html
              design/./templates/default/_modules/Account/ProfileSettings.html
              design/./templates/default/_modules/Account/ProfileSettings.html
              design/./templates/default/_modules/Account/ProfileSettings.html
              design/./templates/default/_modules/Account/ProfileSettings.html
              design/./templates/default/_modules/Account/ProfileSettings.html
              design/./templates/default/_modules/Account/ProfileSettings.html
              design/./templates/default/_modules/Account/ProfileSettings.html
              design/./templates/default/_modules/Account/ProfileSettings.html
              design/./templates/default/_modules/Ads/AdsList.html
              design/./templates/default/_modules/Event/Calendar.html
              design/./templates/default/_modules/Event/AddForm.html
              design/./templates/default/_modules/Event/AddForm.html
              design/./templates/default/_modules/Event/AddForm.html
              design/./templates/default/_modules/Event/AddForm.html
              design/./templates/default/_modules/Event/AddForm.html
              design/./templates/default/_modules/Event/FeaturedEvents.html
              design/./templates/default/_modules/Event/FeaturedEvents.html
              design/./templates/default/_modules/Event/EventView.html
              design/./templates/default/_modules/Event/EditForm.html
              design/./templates/default/_modules/Event/EditForm.html
              design/./templates/default/_modules/Event/EditForm.html
              design/./templates/default/_modules/Event/EditForm.html
              design/./templates/default/_modules/Event/EditForm.html
              design/./templates/default/_modules/Video/Main.html
              design/./templates/default/_modules/Video/AjaxBox.html
              design/./templates/default/_modules/Video/ModifyCategories.html
              design/./templates/default/_modules/Video/ApproveVideos.html
              design/./templates/default/_modules/Video/AjaxLatest.html
              design/./templates/default/_modules/Video/Categories.html
              design/./templates/default/_modules/Video/Browse.html
              design/./templates/default/_modules/Video/View.html
              design/./templates/default/_modules/Blog/NewBlogs.html
              design/./templates/default/_modules/Blog/MemberBlogs.html
              design/./templates/default/_modules/Blog/AddBlog.html
              design/./templates/default/_modules/Blog/MyPageBlogs.html
              design/./templates/default/_modules/Blog/MyPageBlogView.html
              design/./templates/default/_modules/Blog/BlogList.html
              design/./templates/default/_modules/Blog/BlogList.html
              design/./templates/default/_modules/Blog/BlogList.html
              design/./templates/default/_modules/Blog/BlogList.html
              design/./templates/default/_modules/Blog/EditBlog.html
              design/./templates/default/_modules/Blog/EditBlog.html
              design/./templates/default/_modules/Blog/View.html
              design/./templates/default/_modules/Blog/View.html
              design/./templates/default/_modules/Groups/GroupForumPosts.html
              design/./templates/default/_modules/Groups/NewGroups.html
              design/./templates/default/_modules/Groups/GroupDetails.html
              design/./templates/default/_modules/Shoutbox/Box.html
              design/./templates/default/admin/language/options.html
              design/./templates/default/admin/language/options.html
              design/./templates/default/admin/language/options.html
              design/./templates/default/admin/language/missing-options.html
              design/./templates/default/admin/language/add-phrase.html
              design/./templates/default/admin/language/add-phrase.html
              design/./templates/default/admin/language/phrases.html
              design/./templates/default/admin/language/phrases.html
              design/./templates/default/admin/language/phrases.html
              design/./templates/default/admin/language/add-option.html
              design/./templates/default/admin/language/missing.html

              里面会有<{$title|escape}>这样的句子。将”|escape”删掉即可修正汉字bug.
              3.敏感词过滤:phpfox为了扩展性,是在显示时过滤的,没有这个必要。我们把显示层的过小滤去掉,然后在index.php的第一行就加上过滤(如果有post数据,将之过滤)。这样将过滤机制更改之后,CPU又节省不少。
              4.未登陆用户cache层。对于未登陆用户,没必要时时都是显示最新的。又是在index.php的第一行加上过滤:如果用户未登陆且无post数据,则显示cache层的静态文件。有1%的机率更新cache.

              优化之前:

              Document
              Path: /
              Document Length: 23960 bytes
              Concurrency Level: 1
              Time taken for tests: 2.740130 seconds
              Complete requests: 30
              Failed requests: 0
              Write errors: 0
              Total transferred: 733950 bytes
              HTML transferred: 718800 bytes
              Requests per second: 10.95 [#/sec] (mean)
              Time per request: 91.338 [ms] (mean)
              Time per request: 91.338 [ms] (mean, ac

              优化之后:

              Server Software: Apache/2.2.4
              Server Hostname: ***.com
              Server Port:
              80
              Document Path: /
              Document Length: 23960 bytes
              Concurrency Level: 1
              Time taken for tests: 0.32685 seconds
              Complete requests: 30
              Failed requests: 0
              Write errors: 0
              Total transferred: 730560 bytes
              HTML transferred: 718800 bytes
              Requests per second: 917.85 [#/sec] (mean)
              Time per request: 1.090 [ms] (mean)
              Time per request: 1.090 [ms] (mean, across
              all concurrent requests)
              Transfer rate: 21814.29
              [Kbytes/sec] received
              Connection Times (ms)
              min mean[+/-sd] median max
              Connect: 0
              0 0.0
              0 0
              Processing: 0 0
              1.0 1 1
              Waiting: 0
              0 0.3
              0 1
              Total: 0
              0 1.0
              1 1

              又节约了不少资源。

              4。数据库结构修改:

              a.phpfox_online_session,phpfox_online,phpfox_site_session的数据都不需要永久保存。直接改成内存表。

              由于内存表不支持txt类型,因此将tinytxt,text类型的字段均改为varchar字段。

              现在做的改动有:

              phpfox_online:

              user( tinytext) 改为:user(varchar(32)

              page (tinytext )改为page(varchar(100)

              ip(tinytext)改为(varchar(16) )

              phpfox_site_session:

              browser:改为varcahr(64)

              host:改为varchar(32)

              page:改为varchar(64)

              referer:改为varchar(64).

              这个改过之后我试了一下,有些字段长度还可以进一步改小,这样才能将session数据都做成内存表,速度又可以大上一层楼。
              b.flashchat_templates
              这个表非常搞笑,有2万条记录,好像是在”CAN I FUCK YOU”和”<srai>DO YOU WANT TO HAVE
              SEX</srai>”类似的句子之间做替换。基本没用(尤其是对中文).依我的看法如果这个表能导致瓶颈,就清空掉好了。

              c.flashchat_patterns
              这个表巨大无比,有15万条记录。主要是英文。如果可以的话,可以给他瘦身一下。

              d.mysql的连接方式为mysql_connect,这个可以修改为mysql_pconnect。视具体情况。
              e.许多表没有加索引,最搞的是论坛的topic表没有给group_id这个字段加索引。真是让人郁闷。注意把数据库结构整个看一遍,挨个把屁股擦干净。

              5.去掉title中的标识:

              修改include/modules/Site/classes/PhpFox_ComponentSiteTitle.class.php
              中,将第200行的:

              198 if (App::removeBrand())

              199 {

              200 // $sTitle
              .= ‘ (Powered by phpFoX)’;

              201 }

              改掉就行了。(提醒大家,phpfox不允许未付费用户去这个标识。去这个标识需要另付费75$.

              好啦,现在他可以支撑1000人在线了(其实我还加装了php-apc,这个东东把php编译结果缓存起来,另外把图片等静态文件进行了分流)。


              Tag:
              相关文章


                 
                Jul
                26
                Posted (xurenlu) in php性能 on 07月-26-2007

                APC由于能够缓存文件上传进度,因此算是解决了一直以来困挠PHP开发人员的一个老大难,所以我也特别喜欢他了。如果对php实现文件上传进度条有困 难,可以看这里
                不过今天发现,APC宣称的加速功能,其实也是一种缓存,而不是对编译方式,编译过程什么的进行了优化.
                原因是,我把两个程序目录名称对调,结果发现,程序报错了.但是让人郁闷的是,错误提示是在一个已经不存在的文件的109行。后来不管怎么刷新,都是这个结果.后来只好重启web服务器了事.
                看来,APC是把编译好的php文件存放在共享内存中,以后是每过一段特定时间才重新编译一次.对于已经运行的应用,这个将大大节省你的CPU占用(虽然PHP的编译已经非常非常地快了,开启APC缓存后,仍能大副度地加速你的PHP,因为php源文件不需要在每次调用时都要编译了).从原理上说,PHP已经被改造成了Jsp式的静态脚本.只是PHP+APC的组合比Jsp的还要快,因为JSP在运行时会不断检测JSP源文件是否已经被更新,不断检测XML配置文件是否被更新.
                但是,调试期间可能需要重启Apache.
                目前没有在Lighttpd下检测以FastCGI方式运行时加入APC对PHP性能的影响。


                Tag:
                相关文章


                   
                  Jul
                  12
                  Posted (xurenlu) in 未分类 on 07月-12-2007

                  下载站是一类特殊的站点,站长们已经不需要为流量担心了。他们只需要担心服务器的负载了。尤其是现在迅雷等近乎掠压者的软件出现以后。
                  lighttpd是近来日渐流行的一个轻量级,着眼于高负载性能的开源的,免费的web服务器软件。在很多方面比如mod_rewrite方面与行业巨头apache很相似,
                  使得从apache往lighttpd上的迁移成本相对较低。
                  但是个人感觉,lighttpd还是着眼于高负载载上并不失灵活性。例如为了迎合日渐流行的在线视频站点如youtube类站点的胃口,还专门出一个针对flv下载的模块,
                  这个模块相当偏门。
                  lighttpd上还有一个专门针对下载站点的模块:mod_secdownload
                  根据其官方wiki文档,mod_secdownload有四个配置选项:

                  1. secdownload.secret        = <string>
                  2. secdownload.document-root = <string>
                  3. secdownload.uri-prefix    = <string>  (default: /)
                  4. secdownload.timeout       = <short>   (default: 60 seconds)

                  在这个模块出现以前,人们也曾有几个思路去应对盗链:
                  1.修改WEB应用。比如直接通过PHP读取文件内容,发送二进制码。由于发送过程完全可控,这个对访问者的控制完全准确,比如想限制只有登陆用户才可以下载等等,易如反掌。问题是,每一次下载都通过php进行,严重地影响了服务器的效率。磁盘IO,CPU占用都容易跑满。
                  2.编程实施,自行设计一些服务器模块。比如weidy同学以前好像做过IIS下的过滤器,思路是在IIS中通过插入Hook,检测对静态下载文件(zip,exe,rar等文件的HTTP请求头中是否存在一个特定的Cookie,而这个cookie是有有效期的。当然这是可以的,我还有更好的思路,那就是,自己写一个web server,你想干什么就干什么,你要加一个彩蛋以便每当有用户访问时都要你站长大人先按一下电话按键用户才可以继续下载都行…..问题是,不是所有人都会。而且,实施也是一大麻烦。
                  3.基于服务器的现有模块,依照某些访问特性,比如来源页面(HTTP_REFERER)进行限制。但是,现在的盗链网页已经非常聪明了,迅雷更聪明:它能精确地学习前人在下载该软件时的数据,模仿性地发送特定的HTTP_REFERER(说不定将来连COOKIE也一起发送),非常牛B.所以像车东简单地这样写上:

                  1. RewriteEngine on
                  2. RewriteCond %{HTTP_REFERER} !^http://(www\.)?niernier\.com/.*$ [NC]
                  3. RewriteRule \.(mp3|rar)$ http://www.niernier.com/archives/000445.html [R=301,L]
                  4. #RewriteLog "logs/rewrite.log"
                  5. #RewriteLogLevel 3

                  已经没用了,当然用这个防止通过baidu搜mp3还是可以的,对迅雷,没用。某些牛X的网站好像也能突破这种简单的防盗链。

                  好了,现在看看light官方网站给出的办法:
                  首先,某些东西是一定要经常改变的.或者是Cookie,或者是URI,等等。而URI是最好操作的。
                  另外,URI中一定要有一个加密性的东西,在secdownload中,secdownload.secret选项就是让站长自行设置的一个密串。(当然这个密串要足够保密>>>)

                  然后,我们用PHP来生成软件下载链接:

                  1. <?php
                  2.  
                  3. $secret = "verysecret";
                  4. $uri_prefix = "/dl/";
                  5.  
                  6. # filename
                  7. $f = "/secret-file.txt";
                  8.  
                  9. # current timestamp
                  10. $t = time();
                  11.  
                  12. $t_hex = sprintf("%08x", $t);
                  13. $m = md5($secret.$f.$t_hex);
                  14.  
                  15. # generate link
                  16. printf('<a href="%s%s/%s%s">%s</a>',
                  17.        $uri_prefix, $m, $t_hex, $f, $f);
                  18. ?>

                  看到了吗?这个新的链接包含了md5后的密钥(“verysecret”,在lighttpd.conf中指出),同时包含了时间特征串。这个时间串与文件名,密钥一起参与了md5计算,以便对下载客户端提交的URI进行校验。如果不把时间放进去md5,客户端便可以假造URI,任意修改时间串。
                  还是把官方给的lighttpd.conf中的相关配置也给出:

                  1. server.modules = ( ..., "mod_secdownload", ... )
                  2.  
                  3. secdownload.secret          = "verysecret"
                  4. secdownload.document-root   = "/home/www/servers/download-area/"
                  5. secdownload.uri-prefix      = "/dl/"
                  6. secdownload.timeout         = 120

                  现在,把你所有的页面的链接改成用这个php操作运算过的新地址吧。这个新地址被正确地被lighttpd解码并进行传送。
                  有趣的是,如果访问的URL已经超时失效,lighttpd送出的头是“408 Request Timeout” ,这不是一个标准的HTTP协议头,这是为了欺骗一下客户端。

                  当然,没有什么能永远防止疯狂下载。更妥善一点的情况是,这个下载地址并不是在html中直接给出,而是通过javascript来写出。即便是这样,如果hacker们
                  愿意,他也可以让一个firefox在后端访问该页并解析javascript最后遍历dom节点…. 得到该地址。你的地址每2分钟就超时,他也可以每2分钟来造访一次,拿到新地址。但是 有几个网站能够得到这种级别的高手的青睐呢?


                  Tag:
                  相关文章


                     
                    Jun
                    30
                    Posted (xurenlu) in 未分类 on 06月-30-2007


                    前提:
                    Lamp架构(原理上虽然jsp,.net等都一样,但我现在只懂php了)

                    1.用户对准确度的要求是不一样的.银行会要求客户帐上的钱的数目永远是精确的,但是论坛的在线人数,贴子数没这个必要.每天有成千上成的贴子发表。谁会去对质?我们只半个小时算一个甚至每天算一次就行了.所以,应用中要是没加Cron,那就肯定不是一个好应用.想象一下awstats,每当你的老板让你给演示一下前一周的访问周数据时,它就嘎吱嘎吱地算上老半天,然后在你的老板快要睡着时IE终于弹出一个页:服务器超时…. 你就知道要把一些服务设为定时跑一次,而不是时时保持最新最准确了
                    2.瓶颈永远是先在CPU/内存/磁盘IO中的一个出现.他们很少是同时告急的.因此,针对这个设计一个.比如:某台服务器上CPU占用平均为60%左右,而内存占用是5%左右。那么我们可以预先猜测,CPU资源会首先占尽。由于日志显示占用CPU最多的是mysqld进程,说明mysql查询耗尽了CPU.再查之,原来是贴子主题太多,一个表有上G大小,索引不当.
                    找到问题,于是马上做出改进.原来的URL已经优化成***.com/topic/10/10001.html,***.com/topic/12/12001.html…这样的了,但其实后台是用rewrite的.而id从1到100,000的主题都因为已经太老,无人参与回复了,所以没必要每次都查库.马上写个脚本,将***.com/topic/1.html….***.com/topic/10/10001.html…这些页面都读下来,保存为web根下/topic/***/***.html文件。现在这些文件是实际存在的了,Apache会优先读这个静态文件,而不是适用rewriterule了.
                    (注:我的apache 的rewrite规则是这样写的,这样文件找不到的时候会交给index.php来处理.

                    rewriteEngine on
                    RewriteCond %{REQUEST_FILENAME} !-f
                    RewriteCond %{REQUEST_FILENAME} !-d
                    rewriterule . /index.php [L]

                    )
                    现在再看一看,mysqld占CPU是少了不了.但还是不够啊.咱们的内存还没有用上呢。才10%,不行.于是又有了办法:架上squid或是类似缓存服务,大量起用内存缓存,现在就好多了.内存,CPU都用上了.如果这时CPU使用率仍然领先内存,那咱们再启用mem_cache,不过启用mem_cache后要改程序,改得好才能真正提交效率.
                    3.同是数据,用户名跟用户发的贴子内容这两个数据就不一样.一个咱们用varchar存在库中,另一个咱们得用text来存.这两个占用资源也大不一样啊.而且,贴子主题和发表用户名的读取的次数远大于贴子内容读取次数.这也是一个不均衡。于是基于这样的考虑,我把存储贴子数据表分开了。
                    现在的表是这样的:一个表存储用户名,发表时间,贴子标题等信息.另外建10个表,专门用来存储发贴内容.具体存在哪一个表,由这个主题贴ID的最后一位来定.
                    好了,由于发贴内容比较长,我把它分表(为了简化模型,是分表。实际有可能是分库,分服务器)了.而贴子主题由于要进行列表显示,搜索等操作,就没有分表.内容的查询效率是提高了。可是由于贴子主题要进行大量列表显示和搜索,且都在一个表中,还是慢啊.
                    不急,咱再分析.
                    a:这个表中存储的数据都比较短小.
                    b:这个表中常用来做列表显示,用户往往在论坛中是看了第一页标题,可能没什么吸引人的,于是又点了下一页…部分贴子会进去看一下内容.但是你见过用户一直点到第100页吗?而且,用户看贴子的量也绝对大于发贴子….除非他是供职于某论坛的版主….
                    好了,又总结出不均衡性来了.大多数情况下用户只看前100页,那咱们就把这100页数据拿出来,建一个内存表,再放一份.Mysql内存表有一个限制,就是字段不能超过255字节,但咱们的这个表刚好符合.现在咱们写数据时主题表和存主题的内存表中都写入一次,读数据的时候,就从内存表中读…这样是不是快很多了?

                    参考:

                    把握web 开发的平衡与不平衡,
                    http://www.162cm.com/archives/388.html


                    Tag:
                    相关文章


                       
                      Jun
                      29
                      Posted (xurenlu) in 未分类 on 06月-29-2007

                      从某个英文pdf文档译过来的,很久了,还是Mysql Conference 2007时的PDF.
                      (如果能找到,我把原文地址和pdf给出来)
                      向原作者致谢….

                      调整Server Config时需要考虑的事情
                      设置是针对负载的,不存在说有什么针对一个16GB内存的优化方案这种说法.
                      存储引擎的选择或是混用是很重要的
                      有些设置取决于您的硬件和操作系统。

                      Approaching?tuning
                      您只需要设置一部分,其余的一些要具体分析(这些也很难决定如何去调整)
                      有些设置会影响Mysql的行为和安全,要小心
                      有些设置是可以基于连接的,利用这一点!
                      首先优化您的查询,否则您需要重新检阅您的设置。
                      常见错误:
                      运行默认设置。(当然如果您用来在您的本儿上存您的DVD收集资料, 那当然可以)
                      直接使用其他人的My.conf文件,都没检查一下是否符合您的需求。
                      虽然只有一两个查询需要,您仍为它设置了一个巨大的全局设置。您可以这样:
                      SET sort_buffer_size=128000000;

                      set sort_buffer_size=DEFAULT

                      我们能得到的信息:
                      SHOW STATUS
                      SHOW INNODB STATUS
                      操作系统的命令比如:vmstat,iostat,mpstat

                      使用内存:
                      为Mysql server分配更多内存常常带来显著的性能提升.
                      但是分配过多的内存会损失性能甚至是稳定性
                      检查一下:
                      Swapping
                      查看swap IO ,这比简单地使用swap space要好
                      使用了32位以上的地址(确保OS和mysql server都是64位的)

                      战胜Swapping
                      有些操作系统会使用Swap,虽然内存充足。
                      处理好IO cache和swap间的平衡。
                      设置VM子系统为只有在最后一次使用resort的时候才swap
                      tune VM subsystem to use swap only as last resort
                      echo 1 >/proc/sys/vm/swappiness
                      如果在linux上使用innodb可以用直接磁盘IO:
                      innodb_flush_method=O_DIRECt

                      了解一下变量的单位:
                      table_cache=128M
                      错了,它的单位是用个(entries)来衡量的。
                      key_buffer_size=1024
                      错了,key buffer size要用bytes来设定。
                      innodb_max_dirty_pages_pct=8GB
                      这个设置准确无误。

                      了解作用域和内存分配规则
                      key_buffer_size
                      全局的,由所有线程共用。
                      sort_buffer_size
                      需要排序时将内存分配给线程。
                      read_buffer_size:
                      一次性就分配指定大小的内存,虽然可能更小的内存就够了
                      过大的值反而会让事情慢得糟糕
                      更多的分配常常由OS来完成。
                      tmp_table_size:
                      指定一个最大值,在需要的时候会增长到这个值 。
                      调得过大也没什么事

                      细节:
                      关于SHOW STATUS
                      show global status:了解服务器的全局状态。了解负载的好方法。在Mysql4.1和以下版本中唯一一个。
                      show local status:
                      查询/会话配置的好东西
                      从mysql 5.0开始能用
                      show status 默认就是这个
                      有些变量是全局的
                      也出现会在show status 的输出中
                      mysqladmin extended -i100 -r
                      抽样一下,看看Mysql server现在干了些什么,这是个好办法
                      Show status:
                      aborted clients:
                      不用担心,许多程序都没有恰当地关闭连接。
                      aborted_connects:
                      可能意味着认证失败,网络超时或其他错误。
                      值得看一看,因为可能引起主机blocked out
                      max_connect_errors=100000
                      可能意味着有人尝试暴力密码破解
                      binlog_cache_disk_use/binlog_cache_use
                      bin log 溢出到磁盘的频率。
                      如果太频繁,需要增大–binlog_cache_size
                      com_xxx:
                      按查询来了解服务器负载
                      查询可以是相当复杂多样的


                      Tag:
                      相关文章


                         
                        May
                        17
                        Posted (xurenlu) in 未分类 on 05月-17-2007

                        就是adodb.strem那段流传最广,很神奇呢。我那么辛苦写了个模板类,居然只有几个台湾人用,怪。

                        1. <% 
                        2.  
                        3. ’************************************************************* 
                        4. ’转发时请保留此声明信息,这段声明不并会影响你的速度! 
                        5. ’************************************************************* 
                        6.  
                        7.  
                        8. ’************************************************************* 
                        9. ’@author:                        面条 
                        10. ’@realname:                        徐仁禄 
                        11. ’@email:                        xurenlu@sohu.com 
                        12. ’@QQ:                            55547082 
                        13. ’@Homepage:                        http://www.ksdn.net 
                        14. ’@版权申明: 
                        15. ’            非盈利性质团体或者个人可以免费使用. 
                        16. ’************************************************************* 
                        17. ’   我敢担保 本程序由本人独立完成 ,没有参考他人的任何程序(参考了本人自己的php版本的template,不过那个也是本人独立完成的 .)同时本人声明  本class的所有示例版权均为本人所有,任何人或者单位实体不得随意更改 
                        18. ’ 本template可免费用于: 
                        19. ’            1.个人的非商业性质应用。 
                        20. ’            2.公益性质团体,如红十字会,孤儿院等等 
                        21. ’   
                        22. ’具体使用方法请看example.asp文件. 
                        23. ’ 
                        24. ’adSaveCreateOverWrite 
                        25.  
                        26. class template 
                        27.     dim adSaveCreateOverWrite 
                        28.     dim adSaveCreateNotExist 
                        29.     public starttag 
                        30.     public endtag 
                        31.     public filename 
                        32.     dim  key_arr() 
                        33.     dim  val_arr() 
                        34.     public content 
                        35.     public total 
                        36.     public contenta() 
                        37.     public BlockContent ’ 块的内容(解析后的) 
                        38.     public block_begin_delim 
                        39.     public block_end_delim 
                        40.     public block_begin_word 
                        41.     public block_END_word 
                        42.     public block_null 
                        43.       
                        44. sub Class_Initialize()’  类的初始化 
                        45.  redim key_arr(0) 
                        46.  redim val_arr(0) 
                        47.  redim contenta(0) 
                        48.  adSaveCreateOverWrite=2 
                        49.  adSaveCreateNotExist=1 
                        50.  
                        51.  starttag="{" 
                        52.  endtag="}" 
                        53.  total=0 
                        54.  block_begin_word="BEGIN" 
                        55.  block_end_word="END" 
                        56.  block_begin_delim="<!--" 
                        57.  block_end_delim="-->" 
                        58.  block_null=" "    ’  begin 和end之间用空格隔开 
                        59. end sub 
                        60.  
                        61.  
                        62. sub echo (a) 
                        63. response.write a 
                        64. end sub   
                        65.  
                        66.  
                        67. function readfile(filepath) 
                        68.     dim stm2 
                        69.     on error resume next 
                        70.     set stm2 =server.createobject("ADODB.Stream") 
                        71.     stm2.Charset = "gb2312" 
                        72.     stm2.Open 
                        73.     stm2.LoadFromFile filepath 
                        74.     readfile = stm2.ReadText 
                        75. end function   
                        76.  
                        77.  
                        78. function writefile(filepath,str)’ 写入文件的函数 
                        79.     dim stm 
                        80.     on error resume next 
                        81.     Set stm = server.createobject("ADODB.Stream") 
                        82.     stm.Charset = "gb2312" 
                        83.     stm.Open 
                        84.     stm.WriteText str 
                        85.     stm.SaveToFile filepath, adSaveCreateOverWrite 
                        86. end function 
                        87.  
                        88. function SetFile(file)’ 设置文件,读取文件内容 
                        89.     filename=file 
                        90.     content=readfile(file) 
                        91. end function   
                        92.  
                        93. function inarray(val,arr)’val是否在数组arr中 
                        94.     dim tmp,i,rr,re,pt,tt 
                        95.     for i =0 to ubound(arr) 
                        96.     if arr(i)=val then 
                        97.         inarray=i 
                        98.         exit function     
                        99.     end if 
                        100.     next 
                        101.     inarray=-1 ’不在数组中. 
                        102. end function   
                        103.  
                        104. function listarray(arr,str) 
                        105.         dim tmp,i,rr,re,pt,tt 
                        106.         str="   " & str 
                        107.       
                        108.         for i=0 to ubound(arr) 
                        109.             echo str & i & ":" & arr(i) & vbcrlf   
                        110.         next 
                        111. end function   
                        112.  
                        113. function NewKey(key,val) ’添加新的键值. 
                        114.       dim tmp,i,rr,re,pt,tt,pos 
                        115.     i=total   
                        116.     pos=inarray(key,key_arr) 
                        117.       
                        118.     if  pos=-1 then  ’//如果这个键值不存在. 
                        119.           
                        120.      redim Preserve key_arr(i) 
                        121.      redim Preserve val_arr(i) 
                        122.           
                        123.           
                        124.         ’echo "key_arr(" & i & ")=" & key & vbcrlf 
                        125.           
                        126.         key_arr(i)=key 
                        127.         val_arr(i)=val 
                        128.         total=total+1 
                        129.     else 
                        130.         key_arr(pos)=key 
                        131.         val_arr(pos)=val 
                        132.     end if   
                        133. end function   
                        134.  
                        135.  
                        136. function resetKeys()’ 初始化键名数组 
                        137.     redim key_arr(0) 
                        138.     redim val_arr(0) 
                        139.     total=0 
                        140. end function   
                        141.  
                        142.  
                        143. function getTextContent(Tcontent) 
                        144.     dim tmp,i,rr,re,pt,tt 
                        145. ’ 得到把某一个文本段的{}内容替换后的块. 
                        146.     tmp=Tcontent 
                        147.     for i=0 to total -1 
                        148.         tmp=replace(tmp & "",starttag & key_arr(i) & endtag, val_arr(i)& "" )  ’ 替换各个键值. 
                        149.     next 
                        150.     ’  替换{***}类似的东西。 
                        151.     ’  目前暂时先放一放把。 
                        152.       
                        153.     ’’ 
                        154.     ’’ 
                        155.     set re=new RegExp 
                        156.     re.Global=True 
                        157.     re.Ignorecase=True 
                        158.     pt="{([a-zA-Z0-9_]{0,100})}" 
                        159.     re.Pattern=pt 
                        160.     set tt=re.Execute(tmp) 
                        161.       
                        162.       
                        163.     for i= 0 to tt.count -1 
                        164.     tmp=replace(tmp & " ", tt.item(i) & "" ,"") 
                        165.     next 
                        166.     set re=nothing 
                        167.     set tt=nothing 
                        168.     ’’ 
                        169.     ’’ 
                        170.       
                        171.     getTextContent=tmp 
                        172. end function   
                        173.  
                        174.  
                        175. function getText() 
                        176.     dim tmp,i,rr,re,pt,tt 
                        177. ’ 得到把某一个文本段的{}内容替换后的块. 
                        178.     tmp=content 
                        179.     for i=0 to total -1 
                        180.         tmp=replace(tmp & "",starttag & key_arr(i) & endtag & "", val_arr(i) & "" )  ’ 替换各个键值. 
                        181.     next 
                        182.     ’  替换{***}类似的东西。 
                        183.     ’  目前暂时先放一放把。 
                        184.       
                        185.     ’’ 
                        186.     ’’ 
                        187.     set re=new RegExp   ’ 这里是模式匹配的应用  有正规表达式应用高手的指导一下! 
                        188.     re.Global=True 
                        189.     re.Ignorecase=True 
                        190.     pt="{([a-zA-Z0-9_]{0,100})}" 
                        191.     re.Pattern=pt 
                        192.     set tt=re.Execute(tmp) 
                        193.     for i= 0 to tt.count -1 
                        194.     tmp=replace(tmp & "", tt.item(i) & "","") 
                        195.     next 
                        196.     set re=nothing 
                        197.     set tt=nothing 
                        198.     ’’ 
                        199.     ’’ 
                        200.       
                        201.     getText=tmp 
                        202.     content=tmp 
                        203. end function   
                        204.  
                        205.  
                        206. function getBlockContent(block)’ 得到模板内容中某一个块的内容 
                        207.     dim i,pos1,pos2,firststr,secondstr,tempstr 
                        208.     firstStr="<!-- BEGIN " & Block & " -->" 
                        209.     secondStr="<!-- END " & Block & " -->" 
                        210.     pos1=instr(content,firststr) 
                        211.     pos2=instr(content,secondstr) 
                        212.     
                        213.     if  (pos2-pos1)<=0 then 
                        214.       
                        215.     else 
                        216.  
                        217.         tempstr=mid(content,pos1,pos2-pos1) 
                        218.         tempstr=replace(tempstr,firststr,"") 
                        219.         tempstr=replace(tempstr,secondstr,"") 
                        220.                 ’response.write replace(tmpstr,"<--","") 
                        221.     end if 
                        222.     ’response.end 
                        223.       
                        224.     getBlockContent=tempstr ’ 返回该字符串. 
                        225. end function   
                        226.  
                        227.  
                        228. sub tofile(file)’ 输出到某个文件 
                        229.     dim tmp 
                        230.     tmp=gettext() 
                        231.     writefile file,content’ 输出到文件 
                        232. end sub 
                        233.  
                        234.  
                        235. function ParseBlock(block) ’ 到到某一个块的解析后的内容. 
                        236.     dim b,tmp 
                        237.     dim firststr,secondstr,tempstr 
                        238.     b=GetBlockContent(block) ’得到某一个块解析前的内容 
                        239.     tmp=getTextContent(b)’得到这个块解析后的内容. 
                        240.     BlockContent=BlockContent & tmp  ’ 保存起来拉 哈哈。这样就实现了重复显示某一个块. 
                        241.     firstStr="<!-- BEGIN " & Block & " -->" 
                        242.     secondStr="<!-- END " & Block & " -->" 
                        243.     tmp=replace(tmp,firststr,"") 
                        244.     tmp=replace(tmp,secondstr,"") 
                        245.     ParseBlock=tmp   
                        246. end function   
                        247.  
                        248. function replaceBlock(block)’ 把解析了几次的块的内容给替换解析了. 
                        249.     dim con,tmp 
                        250.         dim firststr,secondstr,tempstr 
                        251.           
                        252.     con=GetBlockContent(block) ’得到这个块解析前的内容. 
                        253.     tmp=replace(content & "",con & "",Blockcontent & "") 
                        254.     blockcontent="" 
                        255.       
                        256.     firstStr="<!-- BEGIN " & Block & " -->" 
                        257.     secondStr="<!-- END " & Block & " -->" 
                        258.       
                        259.     tmp=replace(tmp,firststr,"") 
                        260.     tmp=replace(tmp,secondstr,"") 
                        261.       
                        262.     content=tmp   
                        263. end function   
                        264.  
                        265. function replaceBlockforNUll(block)’ 把解析了几次的块的内容给替换解析了. 
                        266.     dim tmp,con 
                        267.     con=GetBlockContent(block) ’得到这个块解析前的内容. 
                        268.     tmp=replace(content & "",con & "","") 
                        269.     blockcontent="" 
                        270.     content=tmp   
                        271. end function   
                        272.  
                        273. function replaceBlockfor(block,deStr)’ 把解析了几次的块的内容给替换解析了. 
                        274.     dim tmp,con 
                        275.     con=GetBlockContent(block) ’得到这个块解析前的内容. 
                        276.     tmp=replace(content & "",con & "",Dstr) 
                        277.     blockcontent="" 
                        278.     content=tmp   
                        279. end function   
                        280. end class 
                        281.  
                        282.  
                        283. %> 
                        284.  
                        285.  
                        286. 2、数据库结果集合操作类
                        287.  
                        288. 程序代码 程序代码
                        289. <% 
                        290.  
                        291. ’************************************************************* 
                        292. ’转发时请保留此声明信息,这段声明不并会影响你的速度! 
                        293. ’************************************************************* 
                        294.  
                        295.  
                        296. ’************************************************************* 
                        297. ’@author:                        面条 
                        298. ’@realname:                        徐仁禄 
                        299. ’@email:                        xurenlu@sohu.com 
                        300. ’@QQ:                            55547082 
                        301. ’@Homepage:                        http://www.ksdn.net 
                        302. ’@版权申明: 
                        303. ’            非盈利性质团体或者个人可以免费使用. 
                        304. ’************************************************************* 
                        305.  
                        306.  
                        307. ’************************************************************* 
                        308. ’************************************************************* 
                        309. ’************************************************************* 
                        310. class Rsclass 
                        311.     private iRs 
                        312.     private isql 
                        313.     private iconn 
                        314.     private closeConn 
                        315.     private openConn 
                        316.  
                        317. ’************************************************************* 
                        318. ’        进行初始化,建立iconn和irs对象. 
                        319. ’************************************************************* 
                        320.     Private Sub Class_initialize()   
                        321.         set iconn=server.createobject("adodb.connection") 
                        322.         set irs=server.createobject("adodb.recordset") 
                        323.     End Sub   
                        324.       
                        325.     public sub connect(connstr) 
                        326.         err.clear 
                        327.         on error resume next 
                        328.         iconn.open connstr 
                        329.         if err.number<>0 then response.write "数据联接出错了." 
                        330.     end sub 
                        331.       
                        332.     public property let conn(connection) 
                        333.         set iconn=connection        ’通过外界传入一个数据库联接. 
                        334.     end property 
                        335.       
                        336.       
                        337.       
                        338.     Private Sub Class_Terminate()   
                        339.         on error resume next 
                        340.         irs.close 
                        341.         iconn.close 
                        342.         set iconn=nothing 
                        343.         set irs=nothing 
                        344.     End Sub   
                        345.  
                        346. ’************************************************************* 
                        347. ’        内容:实现统计功能,一般用select count(*) from table where id>54类似的sql语句. 
                        348. ’************************************************************* 
                        349.     public function getCountBysql(sql) 
                        350.         on error resume next 
                        351.         dim count 
                        352.         count=iconn.execute(sql)(0) 
                        353.         getCountBysql=count 
                        354.         iconn.close 
                        355.     end function   
                        356.       
                        357.       
                        358.       
                        359.  
                        360. ’************************************************************* 
                        361.     public function deleteBySql(sql) 
                        362.         err.clear 
                        363.         on error resume next 
                        364.         iconn.execute(sql) 
                        365.         if err.errcode<>0 then 
                        366.             deleteBysql=false 
                        367.             exit function 
                        368.         end if 
                        369.         deleteBySql=true 
                        370.     end function   
                        371.  
                        372.  
                        373. ’************************************************************* 
                        374.     public function deleteByid(table,column,value) 
                        375.         err.clear 
                        376.         on error resume next 
                        377.         iconn.execute("delete from "&table & " where "&column & "=’"&value & "’") 
                        378.         if err.errcode<>0 then 
                        379.             deleteByid=false 
                        380.             exit function 
                        381.         end if 
                        382.         deleteByid=true 
                        383.     end function   
                        384.  
                        385.  
                        386. ’************************************************************* 
                        387. ’        返回一个词典,用这个词典来装载要添加的对象. 
                        388.     public function getdict() 
                        389.         set getdict=server.createobject("scripting.dictionary")     
                        390.     end function   
                        391.  
                        392. ’************************************************************* 
                        393. ’        增加新的记录. 
                        394.     public function add(obj,table) 
                        395.         dim item 
                        396.         isql="select * from " & table 
                        397.         response.write isql 
                        398.         iRs.open isql,iconn,1,3 
                        399.         irs.addnew 
                        400.         for each item in obj 
                        401.             irs(item)=obj(item) 
                        402.         next   
                        403.         irs.update 
                        404.         irs.close 
                        405.     end function   
                        406.       
                        407.       
                        408.  
                        409. ’************************************************************* 
                        410. ’        得到查询得返回值 
                        411.     public function getquery(sql) 
                        412.         iRs.open sql,iconn,1,1   
                        413.         if irs.eof and irs.bof then 
                        414.             getquery=null 
                        415.         else 
                        416.             set getquery=irs 
                        417.         end if 
                        418.     end function   
                        419.  
                        420.     public function getqueryPage(sql,pageNum,PageSize) 
                        421.         on error resume next 
                        422.         iRs.pageSize=pageSize 
                        423.         iRs.open sql,iconn,1,1   
                        424.         iRs.AbsolutePage=pageNum 
                        425.         if irs.eof and irs.bof then 
                        426.             getqueryPage=null 
                        427.         else 
                        428.             set getqueryPage=irs 
                        429.         end if 
                        430.           
                        431.         response.write "<span style=’color:green;’>"& err.number & err.description &"</span>" 
                        432.     end function   
                        433.       
                        434.       
                        435. ’************************************************************* 
                        436. ’        让结果集移动到第n页. 
                        437.     public function setPage(pageNum,PageSize) 
                        438.         on error resume next 
                        439.         iRs.moveFirst 
                        440.         iRs.move((pageNum-1)*PageSize) 
                        441.     end function   
                        442.  
                        443.  
                        444. end class 
                        445.  
                        446.  
                        447. ’************************************************************* 
                        448. 用法示例: 
                        449. dim cstr 
                        450. dim path 
                        451. path=server.mappath("2data.mdb") 
                        452. cstr= "DBQ="+path+";DefaultDir=;DRIVER={ Microsoft Access Driver (*.mdb)};" 
                        453. dim rec 
                        454. set rec=new RsClass 
                        455. rec.connect(cstr) 
                        456.  
                        457.  
                        458. response.write "************************" 
                        459. set tt=rec.getqueryPage("select top 8 * from help",2,4) 
                        460. response.write tt.recordcount & "<br>" 
                        461. do while not tt.eof   
                        462.     response.write tt(0) &"<br>" 
                        463.     tt.movenext 
                        464. loop 
                        465. tt.movefirst 
                        466. tt.close 
                        467. %> 
                        468.  
                        469.  
                        470.  
                        471. 数据库操作类
                        472.  
                        473. 程序代码 程序代码
                        474. <% 
                        475. ’────────────────────────────────   
                        476. ’功能说明:db类是实现数据库连接的类,里面留有数据库连接字符串接口 
                        477. ’包括模块:无,一般都是被其他模块包括 
                        478. ’调用方法:1、如果使用原有数据库连接,则不用更改数据库连接字符串ConnStr 
                        479. ’             具体操作为:Set DBC=New DataBaseClass 
                        480. ’                         DBC.ConnStr="其他连接字符串" 
                        481. ’          2、方法使用:Set Conn=DBC.OpenConnection()得到一个连接对象 
                        482. ’────────────────────────────────   
                        483. Class dbclass 
                        484. ’────────────────────────────────   
                        485. ’定义变量   
                        486. Private IConnStr   
                        487. ’────────────────────────────────   
                        488. ’ ConnStr属性 
                        489. Public Property Let ConnStr(Val) 
                        490.     IConnStr = Val 
                        491. End Property 
                        492. ’────────────────────────────────   
                        493. ’ ConnStr属性   
                        494. Public Property Get ConnStr() 
                        495.     ConnStr = IConnStr 
                        496. End Property 
                        497. ’────────────────────────────────   
                        498. ’ 类初始化   
                        499. Private Sub Class_initialize()   
                        500. End Sub   
                        501. ’────────────────────────────────   
                        502. ’ 类注销   
                        503. Private Sub Class_Terminate()   
                        504.     ConnStr = Null   
                        505. End Sub   
                        506. ’────────────────────────────────   
                        507. ’ 建立一个连接   
                        508. Public Function OpenConnection()   
                        509.     Dim TempConn 
                        510.     ’On Error Resume Next 
                        511.     Set TempConn = Server.CreateObject("ADODB.Connection") 
                        512.     TempConn.Open ConnStr   
                        513.     Set OpenConnection = TempConn   
                        514.     Set TempConn = Nothing   
                        515.     if Err.Number <> 0 then 
                        516.         Response.Write ("<script>alert(’[系统错误]\n\n数据库连接错误!请检查系统参数设置>>站点常量设置,或者 /inc/const.asp文件!’);</script>")   
                        517.         Response.End 
                        518.     end if 
                        519. End Function   
                        520. End Class 
                        521.  
                        522. %> 
                        523.  
                        524. 基于adodb.stream的文件操作类
                        525.  
                        526. 程序代码 程序代码
                        527. <% 
                        528.  
                        529. ’************************************************************* 
                        530. ’转发时请保留此声明信息,这段声明不并会影响你的速度! 
                        531. ’************************************************************* 
                        532.  
                        533.  
                        534. ’************************************************************* 
                        535. ’@author:                        面条 
                        536. ’@realname:                        徐仁禄 
                        537. ’@email:                        xurenlu@sohu.com 
                        538. ’@QQ:                            55547082 
                        539. ’@Homepage:                        http://www.ksdn.net 
                        540. ’@版权申明: 
                        541. ’            非盈利性质团体或者个人可以免费使用. 
                        542. ’************************************************************* 
                        543.  
                        544.  
                        545. ’************************************************************* 
                        546. ’        类名称:        files 
                        547. ’        类功能:            实现文件读写功能,利用adodb.stream实现,在不支持fso的主机上也可以读写文件. 
                        548. ’************************************************************* 
                        549.  
                        550. class files 
                        551.       
                        552.       
                        553.     private adSaveCreateOverWrite    ’创建文件的时候可以覆盖已经存在的文件. 
                        554.     private adSaveCreateNotExist    ’保存文件的时候如果文件不存在,可以创建文件. 
                        555.  
                        556.  
                        557. ’************************************************************* 
                        558. ’        事件名称:        Class_Initialize() 
                        559. ’        事件发生条件:    类创建时候产生该事件 
                        560. ’        事件内容:        给私有变量赋值 
                        561. ’        事件传入参数:    无 
                        562. ’************************************************************* 
                        563.  
                        564.  
                        565.     sub Class_Initialize() 
                        566.          adSaveCreateOverWrite =2 
                        567.          adSaveCreateNotExist = 1 
                        568.     end sub 
                        569.  
                        570.  
                        571. ’************************************************************* 
                        572. ’        函数名称:        function readfile(filepath) 
                        573. ’        函数内容:        读出文件 
                        574. ’        传入参数:        filepath:要读的文件的绝对路径 
                        575. ’        返回参数:        要读的文件的内容. 
                        576. ’************************************************************* 
                        577. function readfile(filepath) 
                        578.       
                        579.       
                        580.     on error resume next 
                        581.       
                        582.     dim stm2 
                        583.       
                        584.       
                        585.     set stm2 =server.createobject("ADODB.Stream") 
                        586.     stm2.Charset = "gb2312" 
                        587.     stm2.Open 
                        588.     stm2.LoadFromFile filepath 
                        589.     readfile = stm2.ReadText 
                        590. end function   
                        591.  
                        592.  
                        593. ’************************************************************* 
                        594. ’        函数名称:        function writefile(filepath,str) 
                        595. ’        函数内容:        写入文件 
                        596. ’        传入参数:        filepath:要读的文件的绝对路径 
                        597. ’                        str:    要写入的内容 
                        598. ’        返回参数:        无返回 
                        599. ’************************************************************* 
                        600.  
                        601.  
                        602.     function writefile(filepath,str) 
                        603.  
                        604.  
                        605.         on error resume next 
                        606.           
                        607.           
                        608.         Set stm = server.createobject("ADODB.Stream") 
                        609.         stm.Charset = "gb2312" 
                        610.         stm.Open 
                        611.         stm.WriteText str 
                        612.         stm.SaveToFile filepath, adSaveCreateOverWrite 
                        613.     end function 
                        614.       
                        615.       
                        616.  
                        617. ’************************************************************* 
                        618. ’        函数名称:        function copy(filepath_s,filepath_d) 
                        619. ’        函数内容:        读出文件 
                        620. ’        传入参数:        filepath_d:目的文件的绝对路径   
                        621. ’                        filepath_s:源文件路径 
                        622. ’************************************************************* 
                        623. function copy(filepath_s,filepath_d)     
                        624.     on error resume next     
                        625.     dim stm2 
                        626.     set stm2 =server.createobject("ADODB.Stream") 
                        627.     stm2.Charset = "gb2312" 
                        628.     stm2.Open 
                        629.     stm2.LoadFromFile filepath_s 
                        630.     stm2.SaveToFile filepath_d, adSaveCreateOverWrite 
                        631. end function   
                        632.  
                        633.  
                        634. end class 
                        635.  
                        636.  
                        637. %>

                        Tag:
                        相关文章