设为首页 收藏本站
查看: 1416|回复: 0

[经验分享] PHP函数-flock()与之替代方法的看法

[复制链接]

尚未签到

发表于 2015-8-27 09:59:50 | 显示全部楼层 |阅读模式
  首先还是来介绍一下flock()的这个函数:
  函数原型
  bool flock (resource fp, int operation [, int & wouldblock])
  




要取得共享锁定(读取的程序),将 lock 设为 LOCK_SH(PHP 4.0.1 以前的版本设置为 1)。
要取得独占锁定(写入的程序),将 lock 设为 LOCK_EX(PHP 4.0.1 以前的版本中设置为 2)。
要释放锁定(无论共享或独占),将 lock 设为 LOCK_UN(PHP 4.0.1 以前的版本中设置为 3)。
如果不希望 flock() 在锁定时堵塞,则给 lock 加上 LOCK_NB(PHP 4.0.1 以前的版本中设置为 4)。(这是引用W3school的)  
  <?php
$file = fopen(&quot;test.txt&quot;,&quot;w+&quot;);
// 排它性的锁定
if (flock($file,LOCK_EX))
{
fwrite($file,&quot;Write something&quot;);
// release lock
flock($file,LOCK_UN);
}
else
{
echo &quot;Error locking file!&quot;;
}
fclose($file);
?>这是一个一般判断的的例子。
  对于实际的运用,必须将其添加到所有使用的文件脚本中
  但注意:其函数无法再NFS或其他网络文件系统中使用也无法在多线程服务器API中使用。
  更一般的例子有$fp =fopen(&quot;$DOCUMENT_ROOT/../orders/order.txt&quot;,'ab');//这里要注意/../带来的安全性问题
flock($fp , LOCK_EX);
fwrite($fp,$outputstring);
flock($fp,LOCK_UN);
fclose($fp);这里注意如有两个脚本同时申请对一个文件加锁,会导致竞争条件关系,这时候应用DBMS解决
  个人觉得使用flock()函数就是当有2个以上用户同时对同一文件操作时,使用户有序的排队操作,避免出现混乱。
  不知道可否用此函数来避免同时提交导致的刷分的现象
  接下来看一个这个函数的代替用法
  /*FLOCK的不可靠让处理文件IO时很头疼
这个函数降低了FLOCK的不可靠性
注意使用函数前后要IGNOR USER ABOUT以免用户突然关闭浏览器造成文件没写完.
函数返回错误的几种情况概率非常之小*/
<?php
//安全写文件(不会冲突,不使用flock)请不断刷新,数字会累加,不会错过
//一旦返回错误,将可能是属性$lockfile非0777错误(这种可能性极小)
//
function safewrite($filename,$content)
{
$long=0;
$lock_file=$filename.'.lock';
while($long<2)
{
clearstatcache();
if(file_exists($lock_file))
{
usleep(100);
$long=abs( date(&quot;s&quot;)-date (&quot;s&quot;, filemtime($lock_file)));
continue;
}
else
{
@fclose(@fopen($lock_file,'w'));
$fp=@fopen($filename,'w');//无法打开
if($fp===FALSE)return FALSE;
$s=@fwrite($fp        ,$content);
if($s===FALSE)return FALSE; //无法写入
@fclose($fp);
unlink($lock_file);
return TRUE;
}
}
if(!unlink($lock_file))return FALSE;//无法删除锁文件
@fclose(@fopen($lock_file,'w'));
$fp=@fopen($filename,'w');
if($fp===FALSE)return FALSE; //无法打开
$s=@fwrite($fp        ,$content);
if($s===FALSE)return FALSE;//无法写入
@fclose($fp);
unlink($lock_file);
return TRUE;
}


ignore_user_abort (TRUE);
$n=file_get_contents('test');
$n++;
if(safewrite('test',$n))echo $n; else fopen('error','w');
ignore_user_abort (FALSE);
?>但是
  /*本函数的缺陷是,当两个进程同时发现$lockfile不存在,则同时建立文件,会造成冲突
虽然概率很小
数据库有防死锁机制,但目前PHP文件操作很难实现这个功能
如果使用flock,请务必在你的系统下进行测试*/
//可以这样
flock($fp,LOCK_EX);
sleep(5);
/*然后在5秒之内用浏览器开始另一个进程
echo flock($fp,LOCK_SH);
看是否能获得独占锁(或共享锁)
如果不能获得,则表明flock起作用*/还有一个测试方法
  <?php
//本文件保存为flock.php,
ignore_user_abort (TRUE);
$fp=fopen('test','w');
flock($fp,LOCK_EX);
sleep(30);
ignore_user_abort (FALSE);//这里还是请大神考虑下,有一定安全隐患
?>
/*运行上文件后,30秒内运行下文件,即可判断是否FLOCK正常;
30秒后程序停止,之后文件自动解锁*/
<?php
//本文件保存为get_flock.php,一定要在执行flock.php后执行
$fp=fopen('test','w');
if( flock($fp,LOCK_EX|LOCK_NB))echo '当前获得锁定!如果flock.php正在运行,说明flock在你的系统上不能运行';
else  echo '不能获得锁定,flock可以在你的系统上运行';
?>








  


  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-104884-1-1.html 上篇帖子: PHP生成静态页 下篇帖子: PHP多种形式发送邮件
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表