我这里有一个很大的问题,我无法在网络上的任何地方找到答案。
我有一个基本的MVC系统,它有3个组件:模型,视图和控制器。
我有一个index.php文件,其中包含基于访问者URI请求的所有内容。
控制器连接View和Model。我在页面加载时打开一个文件并在那里写一个虚拟文本。问题如下:如果我将sleep(1)放入控制器,要在加载页面之前延迟,访问者可以轻松地多次点击referesh。
文件被打开并插入多行。我试图在文件写入时创建一个会话,如果它存在,我甚至不会写文件。
但是有一个问题。我已多次刷新页面进行测试,即使有会话检查,文件仍然会写入多行。
所以我猜它会通过refereshing得到一个同样的HTTP请求,所有这些请求都会看到没有设置Session变量。
页面加载后,我点击刷新它肯定不会插入任何新行,因为会话存在。当访问者在一次加载时多次刷新页面时会发生此问题。
有什么建议可以避免这种情况吗?
答案 0 :(得分:0)
如果您在具有共享资源的多用户环境中工作,则应使用锁定系统。细菌程序是:
锁的主要优点是它们直接在资源上工作,并且不依赖于访问者浏览器中的cookie,就像会话一样。
您可以通过多种不同方式创建锁。一些资源,如文件,支持自己锁定:
http://php.net/manual/en/function.flock.php
但其他人却没有。您可以创建自己的锁定系统,例如使用数据库表。
锁的问题是有时没有给出解锁命令。您需要创建一种方法来处理这个问题。例如,您可以决定锁定在一段时间后过期。这是最基本的保护类型。有许多更先进的方法来解决这个问题。
答案 1 :(得分:-1)
问题是您需要了解会话的工作原理。会话ID保存到cookie并在页面结束时发送到客户端。如果您不等待PHP完成执行,则每个页面刷新都会有新的会话ID。 我会做什么,它应该适用于99%的情况,即使对于不支持cookie(大多数机器人)的用户是使用用户IP(2个不同的用户有可能使用相同的IP但是〜1%)
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
将$ ip作为uniq用户ID存储在DB中,并且可能有另一个字段时间戳,因此您可以在XX秒后使用户ID失效。 这有一些陷阱,但对许多情况都有效。