zl程序教程

您现在的位置是:首页 >  后端

当前栏目

php多线程上下文中安全写文件实现代码

2023-06-13 09:14:15 时间
复制代码代码如下:

<?php
/**
*@usage:usedtooffersafefilewriteoperationinmultiplethreadscontext,arbitoryfiletype
*@author:RockyZhang
*@time:Nov.112009
*@demo[0]:$handler=mfopen($file,"a+");
*mfwrite($handler,$str);
*/
functionmfopen($file,$mode="w+"){
$tempfile=generateTempfile("./tempdir",$file);
preg_match("/b/i",$mode)||($mode.="b");//"b"isrecommended
if(preg_match("/\w|a/i",$mode)&&!is_writable($file)){
exit("{$file}isnotwritable!");
}
$filemtime=$filemtime2=0;
$tempdir=dirname($tempfile);
is_dir($tempdir)||mkdir($tempdir,0777);
do{//do-whileusedtoavoidmodifyinalongtimecopy
clearstatcache();
$filemtime=filemtime($file);
copy($file,$tempfile);
$filemtime2=filemtime($file);
}while(($filemtime2-$filemtime)!=0);
if(!$handler=fopen($tempfile,$mode)){
exit("Failonopeningtempfile,writeauthenticationismustontemporarydir!");
}
returnarray(0=>$handler,1=>$filemtime,2=>$file,3=>$tempfile,4=>$mode);
}

//Idothinkthatthisfunctionshouldbeoptimizedfurther
functionmfwrite(&$handler,$str=""){
if(strlen($str)>0){
$num=fwrite($handler[0],$str);
fflush($handler[0]);
}
clearstatcache();
$mtime=filemtime($handler[2]);
if($mtime==$handler[1]){//comparebetweensourcefileandtemporaryfile
if($num&&$num>0){//temporaryfilehasbeenupdated,copytosourcefile
copy($handler[3],$handler[2])||exit;
$handler[1]=filemtime($handler[3]);
touch($handler[2],$handler[1],$handler[1]);
}
}else{//sourcefilehasbeenmodified,loadsourcefiletotemporaryfile
copy($handler[2],$handler[3])||exit;
touch($handler[3],$mtime,$mtime);
$handler[1]=$mtime;
}
}

functiongenerateTempfile($tempdir="tempdir",$file){
$rand=md5(microtime());
return"{$tempdir}/{$rand}_".$file;
}
?>