1

Apologies for having to ask. In short I'm making a simple imageboard with a "like" button for each image. The number of clicks (likes) stores in 'counter.txt' file in the following format:

click-001||15
click-002||7
click-003||10

Clicking the buttons initiates a small php code via AJAX. counter.php:

<?php
$file = 'counter.txt'; // path to text file that stores counts
$fh = fopen($file, 'r+');
$id = $_REQUEST['id']; // posted from page
$lines = '';
while(!feof($fh)){
    $line = explode('||', fgets($fh));
    $item = trim($line[0]);
    $num = trim($line[1]);
    if(!empty($item)){
        if($item == $id){
            $num++; // increment count by 1
            echo $num;
            }
        $lines .= "$item||$num\r\n";
        }
    } 
file_put_contents($file, $lines);
fclose($fh);

?>  

So when I run the website and testclick my buttons I get the following message:

Notice: Undefined offset: 1 in C:\wamp64\www\wogue\counter.php on line 18

I figured that the script 'counter.php' creates a whitespace on a new string in 'counter.txt' and so it fails to 'explode' and thus make a [1] index. The way I figured that is by backspacing the last empty line in .txt file and saving it. It ran without errors until I clicked a button a few times then the same error appeared.

The piece of code in index looks like this:

<?php 
$clickcount = explode("\n", file_get_contents('counter.txt'));
foreach($clickcount as $line){
    $tmp = explode('||', $line);
    $count[trim($tmp[0])] = trim($tmp[1]);
    }
?>

Any ideas?..

  • You should really use a DB for this. It will be simpler and perform better. You could replace `$clickcount = explode("\n", file_get_contents('counter.txt'));` with `$clickcount = file('counter.txt');` – user3783243 Oct 01 '18 at 16:26
  • Yeah, probably. This is not the best method. – Cyril Alekseyev Oct 01 '18 at 17:44
  • Rather than modifying the question to include `solved` you should either select one of the answers, or post your own answer. To accept an answer see https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work. – user3783243 Oct 01 '18 at 17:52

2 Answers2

0

Trim $line and if it is not empty - do what you need:

$line = trim(fgets($fh));
if ($line) {
    $line = explode('||', $line);
    $item = trim($line[0]);
    $num = trim($line[1]);
    if(!empty($item)){
        if($item == $id){
            $num++; // increment count by 1
            echo $num;
        }
        $lines .= "$item||$num\r\n";
    }
} 

Or check with empty this way:

$line = explode('||', fgets($fh));
if(!empty(line[0]) && !empty($line[1])){
    if(line[0] == $id){
        $line[1]++; // increment count by 1
        echo $line[1];
    }
    $lines .= "{$line[0]}||{$line[1]}\r\n";
}
} 
u_mulder
  • 54,101
  • 5
  • 48
  • 64
0

You are writing using \r\n as a line separator in counter.php and reading the same file exploding only for \n. You should be consistent.

Just removing the \n should be enough to avoid the extra "space" you're seeing.

<?php
$file = 'counter.txt'; // path to text file that stores counts
$fh = fopen($file, 'r+');
$id = $_REQUEST['id']; // posted from page
$lines = '';
while(!feof($fh)){
    $line = explode('||', fgets($fh));
    $item = trim($line[0]);
    $num = trim($line[1]);
    if(!empty($item)){
        if($item == $id){
            $num++; // increment count by 1
            echo $num;
            }
        $lines .= "$item||$num\n"; //removing the \r here
        }
    } 
file_put_contents($file, $lines);
fclose($fh);

?>  
Diogo Sgrillo
  • 2,601
  • 1
  • 18
  • 28