我想对文件进行读-修改-写操作,但是我具有排他锁。显然,我可以使用flock()并执行序列fopen,flock,fread,fwrite,flock,fclose,但是如果我可以使用file_get_contents和file_put_contents,我的代码看起来会更整洁。但是,我需要锁定两个进程,并且我想知道是否可以使用“某种方式”的羊群来做到这一点。危险当然是,我会写一些看起来可行但实际上没有锁定任何东西的东西:-)
答案 0 :(得分:0)
@jonathan说过,您可以将LOCK_EX标志与file_put_contents一起使用,但是对于file_get_contents,您可以构建自己的自定义函数,然后在代码中使用它。 以下代码可能是您的起点:
function fget_contents($path,$operation=LOCK_EX|LOCK_NB,&$wouldblock=0,$use_include_path = false ,$context=NULL ,$offset = 0 ,$maxlen=null){
if(!file_exists($path)||!is_readable($path)){
trigger_error("fget_contents($path): failed to open stream: No such file or directory in",E_USER_WARNING);
return false;
}
if($maxlen<0){
trigger_error("fget_contents(): length must be greater than or equal to zero",E_USER_WARNING);
return false;
}
$maxlen=is_null($maxlen)?filesize($path):$maxlen;
$context=!is_resource($context)?NULL:$context;
$use_include_path=($use_include_path!==false&&$use_include_path!==FILE_USE_INCLUDE_PATH)?false:$use_include_path;
if(is_resource($context))
$resource=fopen($path,'r',(bool)$use_include_path,$context);
else
$resource=fopen($path,'r',(bool)$use_include_path);
$operation=($operation!==LOCK_EX|LOCK_NB&&$operation!==LOCK_SH|LOCK_NB&&$operation!==LOCK_EX&&$operation!==LOCK_SH)?LOCK_EX|LOCK_NB:$operation;
if(!flock($resource,$operation,$wouldblock)){
trigger_error("fget_contents(): the file can't be locked",E_USER_WARNING);
return false;
}
if(-1===fseek($resource,$offset)){
trigger_error("fget_contents(): can't move to offset $offset.The stream doesn't support fseek ",E_USER_WARNING);
return false;
}
$contents=fread($resource,$maxlen);
flock($resource, LOCK_UN);
fclose($resource);
return $contents;
}
进行一些解释:
我只是将flock
的参数与file_get_contents
的参数组合在一起,所以您只需要阅读有关这两个函数的详细信息即可理解代码。但是,如果不需要该函数的高级用法,您可以做
$variable=fget_contents($yourpathhere);
我认为这行与:
$variable=file_get_contents($yourpathhere);
除了fget_contents实际上会根据您的标志锁定文件...