• Advertisement
Sign in to follow this  

[web] PHP File reading/writing question

This topic is 4219 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

let's say i want to make a counter of total visitor...and i don't have a database (let's say i can't use one, because it's in the spec). now i can use a file in PHP right? my problem is, won't there be a concurrency issue? like if both users access the file, whose current count is 32, then both of them would've updated the file to 33, when it should be 34 already (since there are 2 of them who viewed the site). does this happen in PHP? how to solve this? thanks!

Share this post


Link to post
Share on other sites
Advertisement
Well you set a cookie so there won't be any trouble that way...the code checks if you have been on the site before...

[source language="php"]
<?php
$visitor_ip = $HTTP_COOKIE_VARS["user_ip"];
$counter = "counter.txt";
$counter_file_line = file($counter);

if(!$visitor_ip)
{
setcookie("user_ip", $REMOTE_ADDR, time()+360000);
$counter_file_line[0]++;
$cf = fopen($counter, "w+");
fputs($cf, "$counter_file_line[0]");
fclose($cf);
}
elseif($visitor_ip != $REMOTE_ADDR)
{
$counter_file_line[0]++;
$cf = fopen($counter, "w+");
fputs($cf, "$counter_file_line[0]");
fclose($cf);
}
?>




This code checks if you have been on the page with the same ip address, if you have, it writes a notation and close the file again. Else it sets a cookie and writes to the file and close it.

Share this post


Link to post
Share on other sites
alright got it! thanks! :)

I have another problem though, how to write new line in a file? I've tried the \n character, but it doesn't work?

here's my code sample:


fputs($fptr, "Hello\nWorld");


But I get "HelloWorld" as a result. Why?

thanks.

Share this post


Link to post
Share on other sites
\n works, but not in notepad. Try opening the file in something like wordpad and you will notice the newlines, if you want to fix this problem use \r\n (windows linebreak)

Share this post


Link to post
Share on other sites
oh you're right...hmm...if i use \r\n instead, will there be any issue in other OS (linux) when viewing that text file?

thanks!

Share this post


Link to post
Share on other sites
As far as the concurrency issue is concerned, yes, this is a real issue. If you have a platform where file locking works properly (i.e. most platforms unless you're using a remote filesystem), you can do something like


$f = fopen("counter.txt", "r+"); // Notice mode - reading *AND* writing.
flock($f, LOCK_EX); // Should block the thread until an exclusive lock is available
// Now read the old counter
$count = (int) stream_get_contents($f);
$count ++;
// Rewind and truncate the file (NOTE: we must NOT close the file, that would create a race condition)
fseek($f, 0);
ftruncate($f, 0);
fwrite($f, $count); // write the new counter
fclose($f); // automatically unlocks our lock.



Besides a bit of error checking (depends on your error handler; mine throw an exception on any warning or notice of any kind)- that should work. Untested.

Mark

Share this post


Link to post
Share on other sites
Obviously test it by:

- Running it from the CLI
- Stick a massive sleep() in between the read and write in the above
- Run several copies at once to ensure that the locking really does work

Don't just trust that it's right.

Mark

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement