我想知道session_write_close()
做了什么。我发现手册有点模糊。
我有一些非常大的SELECT
查询。在SELECT
次session_write_close()
次查询之前,我正在调用session_start()
,在查询之后我再次呼叫SELECT
。
你可能想知道为什么我这样做,如果我没有并且用户正在执行其中一个session_write_close()
查询并中止它们(例如试图打开另一个页面),则用户可以&#39 ; t打开新页面(或必须等待很长时间)。我认为因为脚本正在等待大型查询完成。
所以我的问题:
session_write_close()
在查询之前调用它时究竟做了什么?
为什么用户在打开新页面时,在中止查询时不得不等待(在查询之前使用{{1}})?
提前致谢
答案 0 :(得分:5)
PHP的默认会话存储只是硬盘上的一个文件。即,$_SESSION
的内容只是简单地转储到磁盘上的文件中。当您致电session_start
时,将读取该文件并填充$_SESSION
,当脚本结束时,$_SESSION
将被写回磁盘。
这里很容易进入经典的比赛状态。如果两个请求并行进入,并且从文件中读取了两个独立的脚本,那么稍后两个脚本会回写到文件中...哪一个获胜?该文件的内容是什么,可能是否有一些数据被覆盖?
解决方案是文件锁定。 PHP获取会话文件的锁定,阻止其他任何人读取或写入它,直到锁定被解除。如果两个并行脚本同时尝试获取锁,则其中一个必须等到另一个完成。这就是你所看到的。
session_write_close
显式将$_SESSION
内容写入磁盘并放弃锁定。
答案 1 :(得分:2)
我希望下面的图表有助于理解发生了什么;我们正在讨论同一用户的会话(即同一会话ID):
script a | lock | script b
---------------------+------+-----------------
start
open session <- | yes | start
do stuff
close session -> | yes | -> open session
do heavy queries | | do stuff
open session <- | yes | <- script ended
script ended -> | no |
当你不打算使用它时关闭会话,暂时或者直到脚本结束,使其可用于另一个脚本。
请注意,一旦其他脚本运行,会话数据可能已被更改。