-1

I'm trying to increment a counter inside a text file, that counts HTTP responses from some APIs. This part is handled correctly at the moment. The issue I'm having is that when my text file has more than two values that need to be incremented, only one of the fields is updated and I'm not sure what the structure of the explode should be to update the other value.

The structure of the text file is:

api:one
success:1
fail:1

and no matter what response is received, only the fail is updated.

The code section I have at the moment is:

if ($status == "6" OR $status == "2") {
    $filename = '/home/path/to/file/'.basename(__DIR__).'-responses.txt';
    $lines = file($filename);
    if(!is_file($filename)){
        $default = 'api:one' . "\n" . 'success:1' . "\n" . 'fail:1';
        file_put_contents($filename, $default);
    
    } else {
        
        foreach ($lines as $k=>$v) { 
            $exploded = explode(":", $v);

            if ($exploded[0] == "fail") {
                $exploded[1]++;
                $lines[$k] = implode(":", $exploded);
            }        
        }
        file_put_contents($filename, $lines);
    }
} else {
    $filename = '/home/path/to/file/'.basename(__DIR__).'-responses.txt';
    $lines = file($filename);
    if(!is_file($filename)){
        $default = 'api:one' . "\n" . 'success:1' . "\n" . 'fail:1';
        file_put_contents($filename, $default);
    
    } else {
        
        foreach ($lines as $k=>$v) { 
            $exploded = explode(":", $v);

            if ($exploded[0] == "success") {
                $exploded[1]++;
                $lines[$k] = implode(":", $exploded);
            }        
        }
        file_put_contents($filename, $lines);
    }
}
  • 1
    Can you change structure of file? E.g. save it as JSON? Then it would be extra ease to read, modify and save that file – Justinas Oct 16 '20 at 13:47
  • @Justinas I have a shell script that reads the text file and then updates the information in a database. I should probably have started with an easier format to read from, you're right. If I can't find a functioning solution this way, I'll have to rewrite the other script most likely. – MeltingCube Oct 16 '20 at 13:52
  • 1
    You seem to have 2 sets of code which are very similar, would it be better to try and reduce this so that there is less to maintain in the future? – Nigel Ren Oct 16 '20 at 14:12

1 Answers1

2

The problem is that you're not removing the newlines from the lines before you try to increment the numbers. The success line has a newline at the end, and when you try to increment "1\n" it doesn't do anything, since that's not a number.

Use the FILE_IGNORE_NEW_LINES option to remove the newlines when creating the array, then add them back when writing back to the file.

if ($status == "6" OR $status == "2") {
    $filename = '/home/path/to/file/'.basename(__DIR__).'-responses.txt';
    if(!is_file($filename)){
        $default = 'api:one' . "\n" . 'success:1' . "\n" . 'fail:1';
        file_put_contents($filename, $default);
    } else {
        $lines = file($filename, FILE_IGNORE_NEW_LINES);
        foreach ($lines as $k=>$v) { 
            $exploded = explode(":", $v);

            if ($exploded[0] == "fail") {
                $exploded[1]++;
                $lines[$k] = implode(":", $exploded);
            }        
        }
        file_put_contents($filename, implode("\n", $lines));
    }
} else {
    $filename = '/home/path/to/file/'.basename(__DIR__).'-responses.txt';
    if(!is_file($filename)){
        $default = 'api:one' . "\n" . 'success:1' . "\n" . 'fail:1';
        file_put_contents($filename, $default);
    } else {
        $lines = file($filename, FILE_IGNORE_NEW_LINES);
        foreach ($lines as $k=>$v) { 
            $exploded = explode(":", $v);

            if ($exploded[0] == "success") {
                $exploded[1]++;
                $lines[$k] = implode(":", $exploded);
            }        
        }
        file_put_contents($filename, implode("\n", $lines));
    }
}

Also, you should do the check for whether the file exists before you try to read the file.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • That makes total sense, I had gone down the route of trying to use `preg_replace('~[\r\n]+~', '', $v)` at the explode level, but hadn't gotten it to work correctly. Thank you for alerting me to that option – MeltingCube Oct 16 '20 at 14:02
  • 1
    It's needed for `$lines[$k] = implode(":", $exploded);`. An alternative solution would be to make `$v` a reference variable. – Barmar Oct 16 '20 at 15:39
  • @Barmar if you feel like it and have time, this is a great opportunity to demonstrate how to write DRY code. I would be using `preg_replace_callback()`, but that is not to everyone's tastes. Maybe something like https://3v4l.org/tOWlP – mickmackusa Oct 23 '20 at 21:28