首页 > 解决方案 > PHPflock():我可以在文件获取和文件放置内容周围使用它吗(读取-修改-写入)

问题描述

我想在拥有排他锁的同时对文件进行读-修改-写操作。显然,我可以使用flock() 并执行fopen、flock、fread、fwrite、flock、fclose 的序列,但是如果我可以使用file_get_contents 和file_put_contents,我的代码看起来会更整洁。但是,我需要锁定这两个进程,我想知道是否可以“以某种方式”使用群。当然,危险在于我会写一些看似有效但实际上并没有锁定任何东西的东西:-)

标签: phpfile-get-contentsflockfile-put-contents

解决方案


正如@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;
}

稍微解释一下:我只是将参数 forflock与那些参数结合起来,file_get_contents所以你只需要阅读一些关于这两个函数的信息来理解代码。但是,如果你不需要这个函数的高级用法,你可以这样做

 $variable=fget_contents($yourpathhere);

我认为这条线是一样的:

 $variable=file_get_contents($yourpathhere);

除了 fget_contents 实际上会根据您的标志锁定文件...


推荐阅读