I'm using some simple files for caching and some basic user data. I was first just using file_put_contents()
and file_get_contents()
, but realized this could quickly go wrong when traffic starts increasing.
I've been trying to figure out how to do it properly with flock()
, correct file modes, etc, and come up with the following functions. Have I understood things correctly? Will this be safe in most normal use-cases, with small-to-medium web site usage?
class File
{
public static function read($path, $default = NULL)
{
$fp = @fopen($path, 'r');
if( ! $fp)
return $default;
flock($fp, LOCK_SH);
$data = fread($fp, filesize($path));
flock($fp, LOCK_UN);
fclose($fp);
return $data;
}
public static function write($path, $data)
{
self::check(dirname($path));
$fp = fopen($path, 'c');
flock($fp, LOCK_EX);
ftruncate($fp, 0);
fwrite($fp, $data);
fflush($fp);
flock($fp, LOCK_UN);
fclose($fp);
return $data;
}
public static function check($dir)
{
if( ! is_dir($dir))
{
// https://en.wikipedia.org/wiki/Chmod#System_call
@mkdir($dir, 06750, true);
@chmod($dir, 06750);
}
return $dir;
}
}
Some particular things:
- Should using
LOCK_SH
inread
allow for multiple simultaneous reads?
(which will be the bulk of what's happening since writes will happen quite seldom) - Will using
LOCK_EX
inwrite
make sure nobody else is reading or writing while the file is changed? - Will using the directory permission mask
06750
makes sure that- any files created in that directory will get the same permissions as the directory, and
- the directory/file will only be writable by the web server user and readable by its group?
activemq
and one fuse api to write the data into table/file. \$\endgroup\$