I got stuck in a small problem. I have a php-page:
index.php
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<?php
include( 'counter.php' );
?>
</body>
</html>
And the file counter.php
<?php
$fp = fopen("counter.txt", "r+");
if(!$fp){
error_log("Could not open counter.txt");
exit();
}
if(!flock($fp, LOCK_EX)) { // acquire an exclusive lock
error_log("Could not lock");
}
else{
$counter = intval(fread($fp, filesize("counter.txt")));
$counter++;
echo $counter;
ftruncate($fp, 0); // truncate file
fwrite($fp, $counter); // set your data
fflush($fp); // flush output before releasing the lock
flock($fp, LOCK_UN); // release the lock
}
fclose($fp);
?>
and the file counter.txt, which has the content "0" (0)
After running index.php once, the textfile content becomes ^@^@1, and after that it becomes ^@^@^@1
What I want is the 0 to become 1, and then 2
Is there something wrong the code?
It's running on Ubuntu 18, with Apache, and the files with rights are
-rw-rw-r-- 1 emanuel www-data 559 Feb 13 21:56 counter.php
-rw-rw-r-- 1 emanuel www-data 11 Feb 13 22:51 counter.txt
-rw-rw-r-- 1 emanuel www-data 128 Feb 13 22:50 index.php
drwxrwxr-x 2 emanuel www-data 4096 Feb 12 14:55 software
Answer would be appreciated
Use Rewind after ftruncate (took a bit of work to isolate it)
ftruncate($fp, 0); // truncate file
rewind($fp); //rewind the pointer
Or you can just use rewind
instead of ftruncate
, which seems to be the cause of the \0
null bytes. It seems somewhat pointless to do both as if you write after doing rewind it wipes the file out anyway (unless you use a+
append) ...
Looking in the doc's the very first example uses both.
http://php.net/manual/en/function.ftruncate.php
From PHP.net
<?php
$handle = fopen('output.txt', 'r+');
fwrite($handle, 'Really long sentence.');
rewind($handle);
fwrite($handle, 'Foo');
rewind($handle);
echo fread($handle, filesize('output.txt'));
fclose($handle);
?>
Even though the reason why is not explained... I just use rewind()
but I am always lazy so I endeavor to write the least amount of code that I need to, as I write a LOT of code.
Another solution
Trim the contents of your file before using intval
$counter = intval(trim(fread($fp, filesize("counter.txt"))));
In notepad++
[null][null]1
Anyway that was a fun one... thanks!