Norse
Norse

Reputation: 5757

PHP Increment a counting variable in a text file

This seems simple but I can't figure it out.

file_get_contents('count.txt');
$variable_from_file++;
file_put_contents('count.txt', $variable_from_file);

There is only one line of data in count.txt and it is the hits counter. Is there a way to do this?

Upvotes: 6

Views: 11876

Answers (5)

ian.aldrighetti
ian.aldrighetti

Reputation: 388

If you want to be sure no increments go uncounted (which is what CodeCaster is referring to, the script may load count.txt, increment it, while another file is doing the same, then save that, and then only one increment would have been done and not the proper two), you should use fopen.

$filename = "count.txt";

$count = 0;

$fp = fopen( $filename, 'c+' );
flock( $fp, LOCK_EX );
$size = filesize( $filename );

if( $size > 0 ) { 
  // Coerce to largest natural data type.
  $count = fread( $fp, $size ) + 0;

  ftruncate( $fp, 0 );
  fseek( $fp, 0 );
} 

fwrite( $fp, $count + 1 );

flock( $fp, LOCK_UN );
fclose( $fp );

This will lock the file, preventing any others from reading or writing to it while the count is incremented (meaning others would have to wait before they can increment the value).

Upvotes: 15

Simon Rigét
Simon Rigét

Reputation: 2895

There is a slightly funnier way:

file_put_contents("count.txt",@file_get_contents("count.txt")+1);

file_get_contents reads the contents of the counter file.
@ tells PHP to ignore the error of a missing file. The returned false will then be interpreted as the count of 0.
+1 will cause the string to be converted to a number.
file_put_contents then stores the new value in the counter file as a string.

On a very busy system you might want to obtain a file lock first to prevent simultaneous writes. The OS file cache usually makes this method extremely fast.

Upvotes: 5

Robert Wilson
Robert Wilson

Reputation: 669

This works for me though

$count = intval(file_get_contents('count.txt'));
file_put_contents('count.txt', ++$count);
echo file_get_contents('count.txt');

Upvotes: 1

Litty
Litty

Reputation: 1876

Exactly like you did it should work fine. Just capture the data from file_get_contents(), and check if both of those functions were successful.

$var = file_get_contents('count.txt');
if ($var === false) {
    die('Some error message.');
}
$var++;
if (file_put_contents('count.txt', $var) === false) {
    die('Some error message.');
}

Upvotes: 2

CodeCaster
CodeCaster

Reputation: 151594

$variable_from_file = (int)file_get_contents('count.txt');

But notice that this is not thread-safe.

Upvotes: 3

Related Questions