A sideline comment and issue.
A problem I put in much energy to solve,
as I am dealing with flat files with special purpose to act as database,
is the making a nice alternative to PHP:s own File Lock function.
It is unfortunately so, that in several filesystems in use by operation systems OS
this function is useless, without giving any errors about it.
For such a frequently used filesystem as: FAT32 used in Win95, Win98, WinME
will have to use PHP scripts with specially custom written filelock function.
From [man]flock[/man]
Warning
flock() will not work on NFS and many other networked file systems. Check your operating system documentation for more details.
On some operating systems flock() is implemented at the process level. When using a multithreaded server API like ISAPI you may not be able to rely on flock() to protect files against other PHP scripts running in parallel threads of the same server instance!
flock() is not supported on antiquated filesystems like FAT and its derivates and will therefore always return FALSE under this environments (this is especially true for Windows 98 users).
So, after much reading, searching, thinking and help from others and testing,
I ended with this fwrite function a la halojoy:
You better copy it now, right away,
because I will not publish this my hard work again very often, I can promise:
<?php
// fwrite function by halojoy 2005
// including file locking mechanism
// will repeatedly try to access file for write for 0.5 second
// and return TRUE or FALSE depending on Success to write or not
//
// if FILE LOCK DIRECTORY is older than 5 seconds it will remove it by force
// you can set these time-intervalls to suit your environment
// mtimes() is a funtion returning microtime() as seconds
function writefile($fname,$data){
ignore_user_abort(TRUE);
$dname=$fname.'.lock';
if(is_dir($dname)){
if(time()-filemtime($dname)>5)rmdir($dname);
}
$lock=@mkdir($dname);
if($lock==FALSE){
$tstart=$this->mtimes();
do{
if($this->mtimes()-$tstart>0.5)break;
$lock=@mkdir($dname);
}
while($lock==FALSE);
}
$succe=FALSE;
if($lock==TRUE){
$fp=fopen($fname,'wb');
if(fwrite($fp,$data))$succe=TRUE;
fclose($fp);
rmdir($dname);
}
ignore_user_abort(FALSE);
if(!$succe)die('server is busy -> try again in a moment');
return $succe;
}
?>
Finally, why is filelocking important?
Because if my website has 100 people online,
they might try to write to same data file at the same time
and your data can become corrupt and worst case totally lost.
When using Oracle or other serious programs as database add-on to PHP,
this is not a problem for you, but for this database program.
So these programs have a que, operations is a long line of requests, that are processed one by one,
when it comes their turn in the line.
But when many people run 100 php sessions parallell at your webserver
there is no waiting line especially for file writing functions.
This is what PHP function [man]flock[/man] is good for.
When someone has opened a file x for writing, with FLOCK,
noone else can write to file x,
until FLOCK for file x is removed by the one who is doing writing for the moment.
/halojoy - locked up and safe
🙂