snippetphpMinor
File read/write methods
Viewed 0 times
methodsfilewriteread
Problem
I'm using some simple files for caching and some basic user data. I was first just using
I've been trying to figure out how to do it properly with
Some particular things:
(which will be the bulk of what's happening since writes will happen quite seldom)
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_SHinreadallow for multiple simultaneous reads?
(which will be the bulk of what's happening since writes will happen quite seldom)
- Will using
LOCK_EXinwritemake sure nobody else is reading or writing while the file is changed?
- Will using the directory permission mask
06750makes 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?
Solution
Perhaps it would be useful to look at the manual page for the linux function with the same name:
flock() places advisory locks only; given suitable permissions on a file, a process is free to ignore the use of flock() and perform I/O on the file.1
You asked:
Should using
From the linux manual page for
LOCK_SH
Place a shared lock. More than one process may hold a shared lock for a given file at a given time.
Should the
The
While using
I can’t think of a reason the
flock() places advisory locks only; given suitable permissions on a file, a process is free to ignore the use of flock() and perform I/O on the file.1
You asked:
Should using
LOCK_SH in read() allow for multiple simultaneous reads?From the linux manual page for
flock:LOCK_SH
Place a shared lock. More than one process may hold a shared lock for a given file at a given time.
Should the
check() method handle the case where the directory does exist but is not writable (i.e. using is_writable())? And what if the user is not able to update permissions?The
flock() function returns true on success or false on failure 2 so perhaps it would be useful to use those values to determine if subsequent operations should be attempted.While using
file_put_contents() function were you using LOCK_EX in the $flags (i.e. 3rd ) parameter)? If not, that might be a technique to simplify the write function.I can’t think of a reason the
write function would need to return the data to be written- is that imperative for your code?Context
StackExchange Code Review Q#119414, answer score: 3
Revisions (0)
No revisions yet.