2007/12/02 | PHP学习6:制作一个真正的PHP防灌水计数器
类别(网络工程师) | 评论(1) | 阅读(978) | 发表于 21:36
今天重新测试了昨天的代码 发现有一个BUG,

那就是使用TIME_TO_SEC只是转换了时间的秒数,  却没有考虑天数的问题 。

比如昨天登记的时间是8:00  而几天登记的时间是15:00,那么 就会变成一个负数

也就说 做N次 都不可能在添加计数器了 因为它根本不可能大于5秒。

于是,上网找答案,发现还是不少人遇到此问题的,看来TW出的一周学会PHP还“误导”了不少人啊 ,

在一个论坛找到一个模糊的答案 说是用time() 即获得格林威治时间   转成 的秒数,

但也没说的很清楚 。

还有一个比较搞笑的是说把ASC改成DESC  呵呵 这个方法 肯定是不对的。

经过反复测试 ,发现 使用TIME()的话  其实有一个关键点是  在 建立数据库的时候  记录时间的那个字段“time_at”的“类型”要设置成int(255)

因为原来设置的是datetime

这个很关键 如果设置成 time  那就无法记录成秒数了。

看看经过改进后的代码 这次完全可以运行哦  ,呵呵 ,喜欢的朋友转载时麻烦注明是由这里转载的哦。


<?


$ str_time=time();
// 一开始就获得当前的秒数

echo $ str_time;
//这句纯粹是测试用的 

$ mysql_server_name = "localhost";
$ mysql_username = "a";
$ mysql_password = "a";
$ mysql_database = "a";
//-------
$ ip = getenv('REMOTE_ADDR');
//-----------------------------------------------------------select部分
$ conn=mysql_connect( $ mysql_server_name, $ mysql_username, $ mysql_password );

$ sql = "SELECT * FROM `count` WHERE ip = '$ ip' AND name = 'a1'";

//进行查询(选取)可用 sum(*)代替
$ result=mysql_db_query( $ mysql_database, $ sql,$ conn );

//将查询的结果 --> 抓出一笔
$ row=mysql_fetch_row($ result);

//印出该笔资料的所有拦位[阵列]
//print_r($ row);

//清除查询结果
mysql_free_result($ result);


if (!$ row)
{
//建立连线---透过(服务器位置,使用者名称,使用者密码)
$ conn=mysql_connect( $ mysql_server_name, $ mysql_username, $ mysql_password);



//准备好你的SQL语法
$ sql = "INSERT INTO `count` ( `name` , `NEW` , `ip` , `time_at` ) valueS ('a1', '1', '$ ip', '$ str_time' )";

//选择你要处理的资料库
mysql_select_db($ mysql_database,$ conn);

//进行查询(或叫做执行)...
$ result = mysql_query($ sql);

//结束并且释放连线
mysql_close($ conn);

}
else
{
$ conn=mysql_connect( $ mysql_server_name, $ mysql_username, $ mysql_password );


$ sql = "SELECT $ str_time - time_at FROM `count` WHERE ip = '$ ip' AND name = 'a1' ORDER BY `$ str_time - time_at` ASC";

//进行查询(选取)可用 sum(*)代替
$ result=mysql_db_query( $ mysql_database, $ sql,$ conn );

//将查询的结果 --> 抓出一笔
 $ row2=mysql_fetch_row($ result);

//印出该笔资料的所有拦位[阵列]
//print_r($ row); 测试

//清除查询结果
mysql_free_result($ result);

if ($ row2[0]>5)
{

//建立连线---透过(服务器位置,使用者名称,使用者密码)
$ conn=mysql_connect( $ mysql_server_name, $ mysql_username, $ mysql_password);



//准备好你的SQL语法
$ sql = "INSERT INTO `count` ( `name` , `NEW` , `ip` , `time_at` ) valueS ('a1', '1', '$ ip', '$ str_time' )";

//选择你要处理的资料库
mysql_select_db($ mysql_database,$ conn);

//进行查询(或叫做执行)...
$ result = mysql_query($ sql);

//结束并且释放连线
mysql_close($ conn);
//-----------------------------------------------------------select部分
$ conn=mysql_connect( $ mysql_server_name, $ mysql_username, $ mysql_password );

$ sql = "SELECT count(*) FROM `count` WHERE name = 'a1'";

//进行查询(选取)可用 sum(*)代替
$ result=mysql_db_query( $ mysql_database,$ sql,$ conn );

//将查询的结果 --> 抓出一笔
$ row3=mysql_fetch_row($ result);

echo  "5秒 --后---".$ row3[0];

//印出该笔资料的所有拦位[阵列]
//print_r($ row);

//清除查询结果
mysql_free_result($ result);}
else{
$ conn=mysql_connect( $ mysql_server_name, $ mysql_username, $ mysql_password );

$ sql = "SELECT count(*) FROM `count` WHERE name = 'a1'";

//进行查询(选取)可用 sum(*)代替
$ result=mysql_db_query( $ mysql_database,$ sql,$ conn );

//将查询的结果 --> 抓出一笔
$ row4=mysql_fetch_row($ result);



//印出该笔资料的所有拦位[阵列]
//print_r($ row);

//清除查询结果
mysql_free_result($ result);
echo  "5秒 ---内---".$ row4[0];
}



}
?>


——————————————————————————————————————————

这是另一个没有改动前的 有BUG的例子

http://aibiancheng.cn/htm_data/55/0708/629.html

<?php
//-------------------------------------------------------------------------------
//以下为 判断用户IP在规定时间内是否存在记录
      
        // 取得用户IP
        $ ip = getenv("REMOTE_ADDR") ;
              
        //连接数据库
        $ link = mysql_connect('localhost:6033', 'root', 'dclzyf') ;
      
        // 选择数据库
        mysql_select_db('dcl', $ link) ;
      
        //统计表counter中所有符合的记录
        $ sql = "SELECT * FROM `counter` WHERE '$ ip'=ip";
      
        //用PHP发送一条读取表的SQL查询
        $ result = mysql_query($ sql) ;
      
        //从结果集中取得一行作为枚举数组(将$ restlt的值以数组形式赋给$ row)
        $ row = mysql_fetch_row($ result) ; 

        //判断如果IP没有出现在数据库里的话执行
        if (!$ row)
        {
                //添加记录SQL语句
                $ sql = "INSERT INTO `counter` ( `ip` , `time_at` ) VALUES ('$ ip', NOW( ));";
                              
                //用PHP发送一条添加记录的SQL查询
                $ result = mysql_query($ sql) ;
      
        }  else
                {
                        //IP存在,计算最后一次记录的时间和现在的时间之差(用秒表示)
                        $ sql = "SELECT TIME_TO_SEC( now( ) ) - TIME_TO_SEC( time_at ) FROM `counter` WHERE ip = '$ ip' ORDER BY `TIME_TO_SEC( now( ) ) - TIME_TO_SEC( time_at )` ASC ";
                                              
                        //用PHP发送一条读取表的SQL查询
                        $ result = mysql_query($ sql) ;

                        //从结果集中取得一行作为枚举数组(将$ restlt的值以数组形式赋给$ row)
                        $ row = mysql_fetch_row($ result) ; 
                      
                        //相减时间,用于测试(可以看到Array ( [0] => 10 ) 当到10秒的时候就自动添加记录)
                        print_r($ row) ;

                        //如果时间差大于规定时间,则执行
                        if($ row[0]>10)
                        {
                                //添加记录SQL语句
                                $ sql = "INSERT INTO `counter` ( `ip` , `time_at` ) VALUES ('$ ip', NOW( ));";
                                                      
                                //用PHP发送一条添加记录的SQL查询
                                $ result = mysql_query($ sql) ;                      
                        }
                }
      
              

//----------------------------------------------------------------------------------
//以下为 读取MYSQL中记录数
      
        //读取表counter内容的SQL语句
        $ sql = "SELECT COUNT(*) FROM `counter`";
      
        //用PHP发送一条读取表的SQL查询
        $ result = mysql_query($ sql) ;
      
        //从结果集中取得一行作为枚举数组
        $ row = mysql_fetch_row($ result) ; 
      
        //清除查询结果
        mysql_free_result($ result) ;
              
        //关闭数据库
        mysql_close($ link) ;
      
        echo "到访人数为:$ row[0]" ;
?>
0

评论Comments