fopen什么时候失败?

ome*_*ega 3 php file-io fopen

在我的PHP代码中,我打开一个文件并向其附加文本.我用这个代码:

$ourFileHandle = fopen($ourFileName, 'a') or die("can't open file");
Run Code Online (Sandbox Code Playgroud)

加载PHP页面时会发生这种情况.现在如果两个人同时加载PHP页面会发生什么?这个代码是否适用于其中一个人,而另一个人是否会执行die()?一般来说什么时候会fopen失败?

谢谢.

Dav*_*dom 6

TL; DR - 只需使用数据库

这不是一个简单的主题.您正在做的事情肯定不会像多个并发请求那样工作,因为大多数系统将允许所有请求打开文件,并且可能多个脚本将能够同时写入文件,您可能最终如果你这样做,文件中有垃圾.

为此可能的工作有很多种,但我将在这里讨论我认为最可行的三种方法.

  1. 使用数据库.无论你想做什么,这几乎肯定是最好的解决方案.RDBMS将处理所有这些并发问题而不会跳过一个节拍,如果你这样做,你将永远不会遇到任何并发问题.

  2. 使用请求对文件的独占锁定flock().此函数使用建议锁定来防止多个并发进程同时访问该文件.这将满足您对多个PHP进程的需求,但如果它们不支持PHP使用的相同类型的咨询锁定系统,则它可能无法与其他外部程序一起使用.
    flock()"阻止"直到在文件上获取锁定.这意味着它会损害请求并发性 - 只有一个请求可以立即写入文件.此外,它不保证按照请求的顺序提供锁定,因此您可能最终会遇到一个请求永远不会获得文件锁定而后续到达的其他请求的情况.

  3. 使用后台进程来处理文件访问,并让脚本与进程通信.这有点像滚动你自己的版本1)它不适合胆小的人,但它可以在正确完成时用于很好的效果.
    使用此模型,可以使用某种形式的进程间通信将需要写入文件的数据中继到后台(持久)进程.然后,此后台进程管理对文件的写入,确保以完整的顺序写入消息.通常(当使用PHP时)这样的IPC将使用套接字实现.这是非平凡的,但可能是最强大的解决方案.


从更一般的角度来看,fopen()通常由于权限问题或低级操作系统问题而失败.OS还可以提供"真正的"锁定机制,该机制将阻止其他程序打开文件.然而,fopen()由于存在很多可能性,因此难以提供真正的"原因列表可能失败".

显然,如果您尝试以读取模式打开文件并且文件不存在,则会失败.但是,上面的代码是以写入模式打开文件 - 如果文件不存在,则不一定会失败 - 如果目录路径存在且调用进程有权写入该目录,则将创建该文件.