在flock-ed文件上使用file_get_contents是否安全?

时间:2014-03-23 20:59:05

标签: php fopen

从我的老派开发者POV来看,这样做很奇怪:

$f = fopen($this->_fileName, "r");
if ($f===false) {
    throw new Exception("bla");
}
$locked = flock($f, LOCK_SH);
if (!$locked) {
    throw new Exception("bla");
}
$content = file_get_contents($this->_fileName);
flock($f, LOCK_UN);
fclose($f);

或做类似的事情:

$f = fopen($this->_fileName, "r");
if ($f===false) {
    throw new Exception("bla");
}
$locked = flock($f, LOCK_SH);
if (!$locked) {
    throw new Exception("bla");
}
$content = fread($f, filesize($this->_fileName));
flock($f, LOCK_UN);
fclose($f);

即。如果我打开fopen(),我应该一直使用$f。但在我的两个示例中,两个函数不使用$f,我确信他们会尝试打开文件来读取其中的一些信息:file_get_contents()filesize()

我可以做一个循环:

$content = ''; 
while(!feof($f)) 
    $content .= fread($f, 4096); 
flock($f, LOCK_UN);
fclose($f);

但是我记得我前段时间读过这个循环比我建议的两个解决方案要慢得多。这样做最安全,最有效的方法是什么(最安全的是第一个)?

1 个答案:

答案 0 :(得分:3)

是。访问共享资源的所有代码(在本例中为$this->fileName)只需要同意锁定某些内容,而不一定是共享资源。

例如(伪代码):

$lock = flock('/tmp/lockfile'); 
file_put_contents('/etc/foo.ini', 'whatever');
funlock($lock);

请注意,我锁定的东西与我覆盖的东西不同。

但是,传统上flock被应用于共享文件的文件句柄,仅仅因为它比仅为锁定文件打开另一个句柄更容易(并且保存了所述开放的内存分配)。但是,没有要求,只需要程序员轻松。

通常,flock是一种在文件系统之上提供协作,建议,读写锁定机制的方法:它实际上并没有对被锁定的东西做任何事情。