Hits counter in txt file count visitors when open page simultaneously - php

I am using this to count the hits to my website:
$counter_name = "counter.txt";
$f = fopen($counter_name,"r");
$counterVal = fread($f, filesize($counter_name));
fclose($f);
$counterVal++;
$f = fopen($counter_name, "w");
fwrite($f, $counterVal);
fclose($f);
I want to ask you if there could be a problem when 2 or more visitors opens the page at the same time? If yes, how to make this to count all hits?
When (for example) 100 users opens the page at exactly same time, the file won't be locked by one of them?
Thanks a lot!

This may help you:
$filename = "counter.txt";
$number = file_get_contents($filename);
$file = fopen($filename, 'a');
if (flock($file, LOCK_EX)) {
ftruncate($file, 0);
fwrite($file, $number+1);
flock($file, LOCK_UN);
}
fclose($file);

Related

incrementing counter in multiple text file

I'm trying to increment a counter in a multiple text file when a user visit my page, but the code I'm working is not working below is the code
$files = glob("counters/visit/*.txt");
foreach($files as $file) {
$content = file_get_contents($file);
if(!isset($_SESSION['hasVisited'])){
$_SESSION['hasVisited']="yes";
$content++;
$f = fopen($files, "w");
fwrite($f, $content);
fclose($f);
}
}
First make sure that $contentis an integer by doing the following :
$content = intval(file_get_contents($file));
Then you're using :
$f = fopen($files, "w");
Instead of :
$f = fopen($file, "w");
fopen can't accept an array as parameter
Also as mentioned by #alanlittle, if you want all your files to be incremented, you should think about the moment where you set $_SESSION['hasVisited']="yes"; and put it at the end of the loop.

Open txt file grab the number count +1 and save it again

I have a text file number.txt and inside it there is only the number 1.
I'm using the code below to open the file, get the number, add 1, update the content (must be 2) and save it again. My code is not working. Any suggestions?
$fp = fopen('number.txt', 'c+');
flock($fp, LOCK_EX);
$count = (int)fread($fp, filesize('number.txt'));
ftruncate($fp, 0);
fseek($fp, 0);
fwrite($fp, $count + 1);
flock($fp, LOCK_UN);
fclose($fp);
Works for me
<?php
$handle = fopen("test.txt", "r+");
if ($handle) {
$buffer = fgets($handle, 10);
$nCount = (int)$buffer;
rewind($handle );
fputs($handle, $nCount+1);
fclose($handle);
}
?>
You should be able to do this with just
$path = 'number.txt';
file_put_contents($path, 1+(int)file_get_contents($path));

File manipulation in PHP: lock, read, clear, unlock

I want some PHP to do the following in this order:
Gain exclusive lock to a file (waiting if already locked)
Read the contents of the file
Empty the file of all contents
Remove the lock
But any code I'm coming up with one way or another always relinquishes the lock between the reading and writing.
$fp = fopen('status.txt', 'r+');
flock($fp, LOCK_EX);
$str = fread($fp,1000); // [another hack. I just want it to read everything]
unlink('status.txt');
touch('status.txt');
Any ideas? I don't trust anything I do with files.
I think ftruncate can do what you want, since it works on a file that you already have open.
http://www.php.net/manual/en/function.ftruncate.php
Here's their example:
<?php
$filename = 'lorem_ipsum.txt';
$handle = fopen($filename, 'r+');
ftruncate($handle, rand(1, filesize($filename)));
rewind($handle);
echo fread($handle, filesize($filename));
fclose($handle);
?>
So I think what you want then is something like:
$fp = fopen('status.txt', 'r+');
flock($fp, LOCK_EX);
$str = fread($fp, filesize('status.txt'));
ftruncate($fp, 0);
flock($fp, LOCK_UN);
fclose($fp);

Lock the file while reading and writing

I have a file which stores some value. Users can add stuff to that file and the counter in that file is updated. But if two users open the file, they'll get the same counter ($arr['counter']). What should I do? Maybe can I lock the file for one user and release the lock after he updates the counter and add some stuff back to the file? Or PHP already locks the file once is opened and I don't need to worry? Here's my current code:
$handle = fopen($file, 'r');
$contents = fread($handle, filesize($file));
fclose($handle);
$arr = json_decode($contents);
//Add stuff here to $arr and update counter $arr['counter']++
$handle = fopen($file, 'w');
fwrite($handle, json_encode($arr));
fclose($handle);
PHP has the flock function which will lock the file before writing to it, example,
$handle = fopen($file, 'r');
$contents = fread($handle, filesize($file));
fclose($handle);
$arr = json_decode($contents);
//Add stuff here to $arr and update counter $arr['counter']++
$handle = fopen($file, 'w');
if(flock($handle, LOCK_EX))
{
fwrite($handle, json_encode($arr));
flock($handle, LOCK_UN);
}
else
{
// couldn't lock the file
}
fclose($handle);

How do I prepend file to beginning?

In PHP if you write to a file it will write end of that existing file.
How do we prepend a file to write in the beginning of that file?
I have tried rewind($handle) function but seems overwriting if current content is larger than existing.
Any Ideas?
$prepend = 'prepend me please';
$file = '/path/to/file';
$fileContents = file_get_contents($file);
file_put_contents($file, $prepend . $fileContents);
The file_get_contents solution is inefficient for large files. This solution may take longer, depending on the amount of data that needs to be prepended (more is actually better), but it won't eat up memory.
<?php
$cache_new = "Prepend this"; // this gets prepended
$file = "file.dat"; // the file to which $cache_new gets prepended
$handle = fopen($file, "r+");
$len = strlen($cache_new);
$final_len = filesize($file) + $len;
$cache_old = fread($handle, $len);
rewind($handle);
$i = 1;
while (ftell($handle) < $final_len) {
fwrite($handle, $cache_new);
$cache_new = $cache_old;
$cache_old = fread($handle, $len);
fseek($handle, $i * $len);
$i++;
}
?>
$filename = "log.txt";
$file_to_read = #fopen($filename, "r");
$old_text = #fread($file_to_read, 1024); // max 1024
#fclose(file_to_read);
$file_to_write = fopen($filename, "w");
fwrite($file_to_write, "new text".$old_text);
Another (rough) suggestion:
$tempFile = tempnam('/tmp/dir');
$fhandle = fopen($tempFile, 'w');
fwrite($fhandle, 'string to prepend');
$oldFhandle = fopen('/path/to/file', 'r');
while (($buffer = fread($oldFhandle, 10000)) !== false) {
fwrite($fhandle, $buffer);
}
fclose($fhandle);
fclose($oldFhandle);
rename($tempFile, '/path/to/file');
This has the drawback of using a temporary file, but is otherwise pretty efficient.
When using fopen() you can set the mode to set the pointer (ie. the begginng or end.
$afile = fopen("file.txt", "r+");
'r' Open for reading only; place
the file pointer at the beginning of
the file.
'r+' Open for reading and
writing; place the file pointer at the
beginning of the file.
$file = fopen('filepath.txt', 'r+') or die('Error');
$txt = "/n".$string;
fwrite($file, $txt);
fclose($file);
This will add a blank line in the text file, so next time you write to it you replace the blank line. with a blank line and your string.
This is the only and best trick.

Categories