Search code examples
phpfopen

fopen is duplicating the same line


I have a file that looks like this:

1||Allan||34||male||USA||||55.789.980
2||Georg||32||male||USA||||55.756.180
3||Rocky||21||male||USA||[100][200]||55.183.567 

I made a function that when executed adds a given number or removes it if already present, which is $added and equals 100 for this example. This is my code:

$added = $_GET['added']; //100 for this example

$f = fopen($file, "w");
$list = file($file);
foreach ($list as $line) {
    $details = explode("||", $line);
    if (preg_match("~\b$details[0]\b~", 3)) {
        foreach ($details as $key => $value) {
            if ($key == 5) {
                $newline .= str_replace("[" . $added . "]", "", $value);
            } else {
                $newline .= $value . "||";
            }
        }
        $line = $newline . "\n";
    }
    fputs($f, $line);
}
fclose($f);
}

this code is supposed to remove the [100] from the Rocky line since its already present which it kinda does. However, upon further execution instead of adding it back it duplicates the Rocky line and messes it up so the file looks like this:

1||Allan||34||male||USA||||55.789.980
2||Georg||32||male||USA||||55.756.180
3||Rocky||21||male||USA||[100][200]55.183.567

3||Rocky||21||male||USA||[100][200]55.183.567 
||
||

why is it doing this? I cant make any sense out of it...

Thank you.


Solution

  • First, you should read the file before you open it for output, because opening with the w mode truncates the file.

    Second, you don't need to loop over the fields in $details if you just want to change one of them. Just access and assign it by index.

    Then you can put the line back together with implode().

    $list = file($file);
    $f = fopen($file, "w");
    foreach ($list as $line) {
        $details = explode("||", $line);
        if (preg_match("~\b$details[0]\b~", 3)) {
            if (strpos("[$added]", $details[5]) === false) {
                $details[5] = "[$added]" . $details[5];
            } else {
                $details[5] = str_replace("[$added]", "", $details[5]);
            }
            $line = implode('||', $details)
        }
        fputs($f, $line);
    }
    fclose($f);