Here's a handy class to allow retrying a write with flock a set number of times. If it can't flock, it will sleep for a brief random interval and try again. If you have a lot of concurrent writes going on, you can use it to avoid data corruption.
<?php
/**
* Here's a handy class to allow retrying a write with flock a set
* number of times. If it can't flock, it will sleep for a brief random interval
* and try again. If you have a lot of concurrent writes going on, you can use
* it to avoid data corruption.
*
* @link http://php.net/manual/en/function.flock.php#84824
*/
class SafeWriter
{
/**
* Write Data
*
* @param string $path File path.
* @param string $data The data to write.
* @param string $mode Suggested mode 'a' for writing to the end of the
* file.
* @return boolean
*/
public static function writeData($path, $data, $mode = 'a')
{
$fp = fopen($path, $mode);
$retries = 0;
$max_retries = 100;
if (! $fp)
{
// failure
return false;
}
// keep trying to get a lock as long as possible
do
{
if ($retries > 0)
{
usleep(rand(1, 10000));
}
$retries += 1;
}
while (! flock($fp, LOCK_EX) and $retries <= $max_retries);
// couldn't get the lock, give up
if ($retries == $max_retries)
{
// failure
return false;
}
// got the lock, write the data
fwrite($fp, "$data" . PHP_EOL);
// release the lock
flock($fp, LOCK_UN);
fclose($fp);
// success
return true;
}
}
//
// example usage
//
SafeWriter::writeData('temp.txt', 'hello');
?>