是php';s文件\u放置\u内容以安全地从Nginx进行并发读取?

是php';s文件\u放置\u内容以安全地从Nginx进行并发读取?,php,nginx,Php,Nginx,想象一份带有静态文件的在线报纸,就像第一页有标题一样。 html由cron每5分钟运行一次的PHP脚本生成,它将文件写入与Nginx共享的卷上。 脚本通过文件\u put\u contents重写index.html。没有其他进程修改该文件,而Nginx返回其内容 考虑到每秒对index.html的多次读取访问,file\u put\u contents是否安全?如果没有:我可以用什么?不,这不安全。写入文件不是原子的。如果NGIX试图在脚本生成的时候读取文件,它将得到一个部分文件。 这样做:

想象一份带有静态文件的在线报纸,就像第一页有标题一样。 html由cron每5分钟运行一次的PHP脚本生成,它将文件写入与Nginx共享的卷上。 脚本通过
文件\u put\u contents
重写index.html。没有其他进程修改该文件,而Nginx返回其内容


考虑到每秒对
index.html
的多次读取访问,
file\u put\u contents
是否安全?如果没有:我可以用什么?

不,这不安全。写入文件不是原子的。如果NGIX试图在脚本生成的时候读取文件,它将得到一个部分文件。 这样做:

file_put_contents("index.html.new", $new_contents);
rename("index.html.new", "index.html");

重命名将是原子的,因此nginx将获得旧版本或新版本,但不会获得部分文件。

或者,您也可以使用符号链接,因此index.html指向eg index.html.20201215,您只需在每次生成文件后更改该符号链接即可。这样,您就可以拥有所有文件的历史记录。是的,如果您希望保留历史记录并能够轻松还原,这是一个好主意。重命名是否会因为并发而以某种方式失败?否,没有阻止重命名的锁定。