When does fopen fail?

我的未来我决定 提交于 2019-12-23 20:08:32

问题


In my PHP code, I open a file and append text to it. I use this code:

$ourFileHandle = fopen($ourFileName, 'a') or die("can't open file");

This happens when the PHP page is loaded. Now what happens if two people load the PHP page at the same time? Will this code work for one of the persons, and for the other person, will it execute die()? In general, when can fopen fail?

Thanks.


回答1:


TL;DR - Just use a database

This is not a simple subject. What you are doing will definitely not work as desired for multiple concurrent requests, as most systems will allow all requests to open the file, and potentially multiple scripts will be able to write to the file at the same time, you are liable to end up with garbage in the file if you do this.

The possible work around for this are many and varied, but I shall cover the three here that I consider to be the most viable.

  1. Use a database. This is almost certainly the best solution to whatever you are trying to do. An RDBMS will handle all of these concurrency issues without skipping a beat, you will never have any problems with concurrency if you do this.

  2. Request an exclusive lock on the file using flock(). This function uses advisory locking to prevent multiple concurrent processes having access to the file at the same time. This will suit you needs of multiple PHP processes, but it may not work with other external programs if they do not support the same type of advisory locking system that PHP uses.
    flock() "blocks" until a lock is acquired on the file. This means that it will harm request concurrency - only one request will be able to write to the file at once. Moreover, it doesn't guarantee that locks will be served in the order in which they were requested, so you can potentially end up in a situation where one request never obtains a lock on the file while other requests that arrived later are being satisfied.

  3. Use a background process to handle the file access, and have your scripts communicate with the process. This is kind of like rolling your own version of 1) and it is not for the faint of heart, but it can be used to great effect when done correctly.
    Using this model, one uses some form of interprocess communication to relay the data that needs to be written to the file to a background (persistent) process. This background process then manages writes to the file, ensuring that messages are written completely and in the correct order. Usually (when using PHP) such IPC would be implemented with sockets. This is non-trivial, but potentially the most powerful solution.


From a more general point of view, fopen() generally fails because of a permissions issue or a low-level operating system issue. It is also possible for the OS to provide a "true" locking mechanism which will prevent other programs from opening the file. However, a true "list of reasons fopen() may fail" is difficult to provide, because there are so many possibilities.

Obviously if you attempt to open a file in read mode and the file does not exist, this will fail. However you code above is opening the file in write mode - this would not necessarily fail if the file does not exist - if the directory path exists and the calling process has permissions to write to that directory, the file will be created.




回答2:


fopen will fail mostly because of these reasons:

  • file does not exist
  • file permissions do not allow opening of this file (writting, reading, exexuting, etc)
  • file is used by another process (ie. 3rd party application)
  • file is being locked by another PHP script/asset



回答3:


fopen can fail if you haven't got the permissions or there are other low-level os issues, fopening multiple times is no problem, but writing simultaneously to it can cause 'striping', so use a (blocking) flock.



来源:https://stackoverflow.com/questions/15305133/when-does-fopen-fail

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!