停止、多次刷新、Form 重复提交问题

a.php

<?php
sleep(30);
file_put_contents("test.txt", "test");
?>
浏览器里打开 a.php, 约4,5秒后关闭浏览器,30秒后,到空间里看,生成了 test.txt; 又测试:不关闭浏览器,4,5秒后点击浏览器的停止按钮,发现仍然生成了 test.txt。

但是 echo ignore_user_abort() 得到的值是 0 。按照文档说明,为 0 的时候应该是不忽略用户的 disconnect。

无论是关闭浏览器,还是点击停止按钮,浏览器都没有向服务器发出数据包(commview 截包,点停止执行了TCP链接的关闭),apache 怎么知道用户有没有 disconnect? 应该是对于web方式执行php程序的,无论怎么样,php程序都会被执行完成。ignore_user_abort 这个应该是对 命令行方式执行 php 程序有影响,按 ctrl+C 中断执行php程序。(还没有测试这个想法)

----------------

<?php
sleep(30); $i = 0;
while (1) {
	$fname = 'test'. (++$i) . '.txt';
	if (!file_exists($fname)) break;
}
file_put_contents($fname, time());
?>
在浏览器打开3个页面,都打开 http://xxx/a.php  过几秒后点停止按钮,发现生成了  test1.txt  test2.txt test3.txt

----------------

根据这个测试,就可以明确防止 form 重复提交了。form 提交后,php程序开始处理,马上设置一个 $_SESSION['stats'] = 'working'; 如果客户点了提交按钮,过了一段时间还没有看到结果页面,就点了停止,然后刷新了页面,再次提交了,只要先检查 $_SESSION['stats'] ,存在就输出一个html 显示正在提交中。然后 php程序里每完成一个进度的工作,可以设置一次 $_SESSION['stats'] , 这样如果用户多次刷新提交form, 也可以看到进度。 好像比 用 ajax 检查进度方便点, 缺点就是不能主动告诉用户目前的进度,要客户自己刷新才行。

----------------

测试针对的问题

1、客户点了停止

2、多次刷新,重复提交

----------------

网上有很多解决办法,用的最多的是用 token 。

----------------

经过程序测试,使用session的方式不行,因为设置session后,只有php程序执行完了,exit 了,session的内容才会保存到session文件里去。

看来只有用token了,就用 sessionid 作为token值

----------------

<?php
session_start(); echo "start\n";
if (isset($_SESSION['stats'])) {
	echo "pos1\n"; exit;
}
$_SESSION['stats'] = 'begin';
sleep(120);
$_SESSION['stats'] = 'done';
echo "pos2\n"; exit;
?>

浏览器打开 a.php 后,显示了 "start",点停止,然后刷新,commview 截包,可以看到 发出了 Http Header 数据包,但是第二次没有收到返回数据。多次测试都是这个情况,难道sleep能阻塞了全部进程? 百度搜 sleep 阻塞,找到:http://blog.csdn.net/guoerwei/article/details/6535389

元凶是 Session ! 以前也看到过资料,session文件的打开是独占的,排他性的,只是没有理解体会。第一次有输出,第二次发出header包,apache收到了,就去执行a.php,然后在 session_start 这里就被阻塞住了。

只有用数据库了,并且在 sleep之前要用 session_write_close 关闭session 文件,这样才不会导致阻塞。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值