根据大小旋转文本文件

时间:2019-06-06 18:38:16

标签: php laravel

我正尝试将网站的点击记录到一个文本文件中,并且我希望将文本文件的大小限制为某个值。超过限制后,我希望动态创建一个新文件。使用我当前的代码,在超过设置的限制后确实会创建一个新文件,但是其余数据仅存储在该新文件上。

public function storeActivityHitCount(Request $request)
{
    if($request->ajax()  && isset($request->data)){
        $clientIP = request()->ip(); $i= 1;
        $date = date("Y-m-d h:i:sa");
        $data = $clientIP.', '.$date.', '.$request->data;
        $file = public_path().'/adminpanel/hits/activity/activity'.$i.'.txt';
        if(!file_exists($file)){
            fopen($file,"w+");
        }
        $filesize = filesize($file);
        if($filesize >= 76){ $i++;
            $file1 = public_path().'/adminpanel/hits/activity/activity'.$i.'.txt';
            if(!file_exists($file1)){
                fopen($file1,"w+");
            }
            $content = file_get_contents($file1);
            $content .= $data. PHP_EOL;
            $upload_success = file_put_contents($file1, $content);
        }else{
            $content = file_get_contents($file);
            $content .= $data. PHP_EOL;
            $upload_success = file_put_contents($file, $content);
        }
        if($upload_success){
           return Response::json(['status' => 'success'], 200); 
        }
        return Response::json(['status' => 'failed'], 400);
    }
    abort(403);
}

2 个答案:

答案 0 :(得分:1)

我将隔离获取活动日志文件的操作。像使用这样的功能:

function getAvailableActivityLogFile(){
    $looking=true;
    $i=0;
    while($looking){
        $i++;
        $file_path = public_path() . "/adminpanel/hits/activity/activity{$i}.txt";
        // If file does not exist or file is less than 76bytes you have the right candiate 
        if(!file_exists($file_path) || filesize($file_path) < 76){
            $looking=false;
            return fopen($file_path, 'a+');
        }
        // Otherwise keep looking on next iteration. You can also write some logic to have a max of loop iterations or max files to look for also.
    }
}

然后,您可以使用此功能来获取下一个可用文件,而不必为可用文件过多的逻辑而烦恼。在关于我的版本中,应使用fwrite()通过函数返回的文件指针写入文件。

使用a +选项,您将在其中获得一个指针,该指针将在每次对指针的新fwrite操作中将内容附加到文件中。

您还可以编写函数来检索路径而不是指针。

答案 1 :(得分:1)

您的原始代码当然只是尝试另一个文件,然后不管其大小而对其进行写入。您想将该逻辑放入重复的结构中。换句话说,您想查找一个完整的完整文件while

public function storeActivityHitCount(Request $request)
{
    if ($request->ajax() && isset($request->data)) {
        $clientIP = request()->ip();
        $date = date('Y-m-d h:i:sa');
        $data = $clientIP . ', ' . $date . ', ' . $request->data;
        $i = 1;
        $file = public_path() . '/adminpanel/hits/activity/activity' . $i . '.txt';
        while (filesize($file) >= 76 && $i <= 20) {
            $i++;
            $file = public_path() . '/adminpanel/hits/activity/activity' . $i . '.txt';
        }
        if (filesize($file) >= 76) {
            // the loop got away from us
            // do something?
            $upload_success = false;
        } else {
            $upload_success = file_put_contents($file, $content, \FILE_APPEND);
        }
        if ($upload_success) {
            return Response::json(['status' => 'success'], 200); 
        }
        return Response::json(['status' => 'failed'], 400);
    }
    abort(403);
}

我在循环中设置了20次迭代的上限;您通常不希望没有某种转义机制的while循环。

file_put_contents将始终创建一个不存在的文件,因此您不需要使用fopen(并且您也没有使用fclose。)此外,如果您传递FILE_APPEND标志,它将附加到现有文件中;无需获取内容并向其添加内容。

请尝试保持代码的一致性和可读性。一行上有多个命令,控制结构和运算符周围的空格不一致,缩进不一致:所有这些最终导致您比以前更费劲地工作。

当然,这可以通过可能在您的服务器上运行的标准系统工具(例如logrotate)来更好地处理。