简体   繁体   中英

My php script sometime write blank data

I have a simple script, just count how many click on a link, when the link clicked, a php script read "counter.txt" file for link ID/URL/Label/Count then plus 1 on count, write to "counter.txt", then redirect.

counter.txt :

Label 1|1|http://google.com|1
Label 2|2|http://google.us|1
Label 3|3|http://google.uk|1

link.php :

<?php

//gets the content from "counter.txt"
$filecontent = file_get_contents('counter.txt');

//separates the contents of counter.txt by "\n" (spaces)
$filelines = explode("\n", $filecontent);

$url_array = null;

$new_file_content = "";

//for each $filelines variable, assign it as $fileline and execute code
foreach ($filelines AS $fileline)
{
//separates the contents of $fileline by "|"
    $filelines_exploded = explode("|", $fileline);

    //assigns counter.txt label to a variable
    $label       = $filelines_exploded[0];
    //assigns counter.txt id's to a variable
    $click_id    = $filelines_exploded[1];
    //assigns counter.txt url's to a variable
    $click_url   = $filelines_exploded[2];
    //assigns counter.txt click count to a variable
    $click_count = $filelines_exploded[3];

    if ($_REQUEST["id"] == $click_id)
    {
        //$url_array contains all of the variables in an array
        $url_array = $filelines_exploded;
        //string to rebuild the counter.txt file
        $new_file_content .= $label . "|" . $click_id . "|" . $click_url . "|" . ((int) $click_count + 1);
    }
    else

    {
        $new_file_content .= $fileline;
    }
    //adds a line break when rebuilding the counter.txt
    $new_file_content .= "\n";
}
//file_put_contents to rewrite the file
file_put_contents('counter.txt', trim($new_file_content));
//redirects to the link gathered from the counter.txt file
header("HTTP/1.1 301 Moved Permanently"); 
header('Location: ' . $url_array[2]);
exit;
?>

Script working but sometime, counter.txt become blank, lost all data, i don't know why, please take a look what wrong with my code.

Thanks/

This can happen during a race condition where two visitors click your link at very near the same time, causing the 2nd instance to read your file just as the 1st instance has cleared it out before writing. This results in instance 2 writing a blank file.

For starters, you can make this somewhat less of a problem by using the flag FILE_APPEND in your file_put_contents, such that you're only appending the new click to the end of the file, instead of rewriting entirely.

Next, you could try using PHP's function flock() to try and obtain a write-lock on the file in question. If your script obtains and obeys the flock() file lock, you can prevent the race condition from occurring at the cost of all your threads blocking until they can get their turn at the file.

In my opinion, though ... if you have to start worrying about race conditions like this, you might be ready to move this system over to your database, where you won't have to worry about writing new click rows simultaneously, or worrying about recalculating sumstats simultaneously, and even if you do - it's very easy to lock tables in most database engines (where as sometimes flock() seems to be unreliable in certain configurations).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM