<?php
$path=dirname(__FILE__)."/eceye_cache/count_visit.txt";
$array=file($path);
if (!is_array($array)) {
die("统计文件出错!");
}//load
$today=intval($array[0]);
$today_date=date("j");
$yesterdayArray=explode("|",$array[1]);
$yesterday=intval($yesterdayArray[0]);
$record_date=intval($yesterdayArray[1]);
$total=intval($array[2]);
//write data 
if (!$_COOKIE['is_visited']) {
//今日量加一
$today=$today+1;
//访问总量加一
$total=$total+1;
//如果第二行记录的日期与今日不等
if ($today_date != $record_date) {
//将今日访问量写入昨天,同时将今日访问清零
$yesterday_str=$today . "|" . $today_date;
$today=1 ;
}else{
//如果第二行记录距离现在没有24小时
//保持昨日统计信息不变,今日统计加一
$today=$today;
$yesterday_str=$yesterday . "|" . $record_date;
}


$temp=$today."\n".$yesterday_str."\n".$total;
file_put_contents($path,$temp,LOCK_EX);
echo("<script src='http://{$_SERVER['HTTP_HOST']}/count_visit_setcookie.php'></script>");
}
//out put
echo "今日:{$array[0]}人次<br>昨日:{$yesterdayArray[0]}人次<br>总计:{$array[2]}人次";
?>count_visit.txt内容:
3
4|16
3261
错误现象,在测试时发现,当并发达到一定数量时,会出现数据丢失现象(即count_visit.txt第二行,第三行都被清空),然后重新计数。在实际运行中发现同样的问题,当访问量稍微高一点总访问量、昨日访问量等都被丢失重新计算。

解决方案 »

  1.   

    应该是并发问题,读得时候同时写了。
    可以使用flock 来处理这个事情。另外写数据库是件比较好的办法。
      

  2.   

    用flock进行锁定设置.不过其有局限性.具体用法直接看手册吧.
      

  3.   

    没怎样看你的代码
    不过...用数据库SQL做吧
    多进程PHP没有完美解决方案
    即使做到都没有数据库做得好另外提供你一个方法,可能有改善
    将file_put_contents放到程式最后
    即运行完file_put_contents立即终结
      

  4.   


    使用Flock函数对文件进行写入锁定,然后慢慢写入,不用当心数据丢失。用数据库最好,但是数据库在大的并发性是也会出现数据丢失,数据乱套的现象,用事务可以解决。
      

  5.   

    //file_put_contents($path,$temp,LOCK_EX);替换成
        if(@$fp = fopen($path, 'w')) {
    flock($fp, 2);
    fwrite($fp, $temp);
    fclose($fp);
    } else {
    exit('写入文件错误!');
    }
      

  6.   

    今天忘记上CSDN
    现在才看到大家这么多热心回复
    其实我早就尝试过使用flock函数
    代码和这位兄弟的差不多:
     if(@$fp = fopen($path, 'w')) { 
    flock($fp, 2); 
    fwrite($fp, $temp); 
    fclose($fp); 
    } else { 
    exit('写入文件错误!'); 
    }我的代码只是在写入完成后多了一个unlock
    这种锁定的方式仍然会出问题,只是稍微好一点点而已
    是不是PHP的内部运行机制就天生存在此问题呢
      

  7.   


    所有的程序(ASP、JSP)都会出现的错误,你说连数据库那么好的引擎也会出现写入错误的现象,文件操作会不出现这样的错误吗????看来,楼主可以用sleep函数停一下再执行。代码:
    <?php
    $path=dirname(__FILE__)."/eceye_cache/count_visit.txt";
    $array=file($path);
    if (!is_array($array)) {
        die("统计文件出错!");
    }//load
    $today=intval($array[0]);
    $today_date=date("j");
    $yesterdayArray=explode("|",$array[1]);
    $yesterday=intval($yesterdayArray[0]);
    $record_date=intval($yesterdayArray[1]);
    $total=intval($array[2]);
    //write data 
    if (!$_COOKIE['is_visited']) {
        //今日量加一
        $today=$today+1;
        //访问总量加一
        $total=$total+1;
        //如果第二行记录的日期与今日不等
        if ($today_date != $record_date) {
            //将今日访问量写入昨天,同时将今日访问清零
            $yesterday_str=$today . "|" . $today_date;
            $today=1 ;
        }else{
            //如果第二行记录距离现在没有24小时
            //保持昨日统计信息不变,今日统计加一
            $today=$today;
            $yesterday_str=$yesterday . "|" . $record_date;
        }
        
        
        $temp=$today."\n".$yesterday_str."\n".$total;
        sleep(1);//停1秒
        file_put_contents($path,$temp,LOCK_EX);
        echo("<script src='http://{$_SERVER['HTTP_HOST']}/count_visit_setcookie.php'></script>");
    }
    //out put
    echo "今日:{$array[0]}人次<br>昨日:{$yesterdayArray[0]}人次<br>总计:{$array[2]}人次";
      

  8.   

    和我同样的问题 一天大概有 60G的文件写入 一小时大概会有 5-6百条的错误数据  ,一群SB 什么也不明白 还非要找错误
      

  9.   

    这是我几年前发的帖子,我的代码确实是写错了(锁定类型用错),采用安全线程的情况下,PHP非常稳定(在改正错误后,至今运行没有出过问题,日PV10多W)。
    不过楼上的写入量有点恐怖,这样大的数据我没接触过,所以不发表看法。
      

  10.   

    我把正确的代码发出来,给后人参考吧:<?php
    $path=dirname(__FILE__)."/eceye_cache/count_visit.txt";
    $handle=fopen($path,"r");
    if ($handle) {
    if(!flock($handle,LOCK_EX)){
    echo "<script>alert('读取锁定失败,请将此问题报告给我们,谢谢!')</script>";
    }
    $array=file($path);
    flock($handle,LOCK_UN);
    fclose($handle);
    }if (!is_array($array)) {
    die("统计文件出错!");
    }//load
    $today=intval($array[0]);
    $today_date=date("j");
    $yesterdayArray=explode("|",$array[1]);
    $yesterday=intval($yesterdayArray[0]);
    $record_date=intval($yesterdayArray[1]);
    $total=intval($array[2]);
    //write data 
    if (!$_COOKIE['is_visited']) {
    //今日量加一
    $today=$today+1;
    //访问总量加一
    $total=$total+1;
    //如果第二行记录的日期与今日不等
    if ($today_date != $record_date) {
    //将今日访问量写入昨天,同时将今日访问清零
    $yesterday_str=$today . "|" . $today_date;
    $today=1 ;
    }else{
    //如果第二行记录距离现在没有24小时
    //保持昨日统计信息不变,今日统计加一
    $today=$today;
    $yesterday_str=$yesterday . "|" . $record_date;
    }


    $temp=$today."\n".$yesterday_str."\n".$total;
    file_put_contents($path,$temp,LOCK_EX);
    echo("<script src='http://{$_SERVER['HTTP_HOST']}/count_visit_setcookie.php'></script>");
    }
    //out put
    echo "今日:{$array[0]}人次<br>昨日:{$yesterdayArray[0]}人次<br>总计:{$array[2]}人次";