Skip to main content
gamedev.net
🔒 Locked

[web] PHP File reading/writing question

Started by _nomad_ Jul 4, 2006 at 2:18 AM 6 replies 1.1k views
Original Post
_nomad_
_nomad_
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!
walle
walle
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.
_nomad_
_nomad_
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.
Aidamina
Aidamina
\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)
-->My Site<--
_nomad_
_nomad_
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!
markr
markr
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 counterfclose($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
_nomad_
_nomad_
i see...alright i'll try that markr. thanks!!
markr
markr
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

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.