我正在开设一个像这样的外部网店的网站:
$webshopurl = "webshop.com/something/?id=" . $transaction_id; //and some other parameters
header ( "Connection: close" );
header ( "Location: " . $webshopurl );
header ( "Content-Length: " . $length );
$response= getResponse($transaction id /*and some other stuff*/);
getResponse()包含一个lopp,它持续轮询网上商店以查看交易的进展情况,并在交易完成时作出相应的反应,或者在10分钟后退出超时。在大多数浏览器上它工作正常,浏览器进入网上商店,用户购买,一旦事务结束,轮询循环获取信息并做它做的任何事情。但是,在PHP停止运行之前,IE不会重定向,因此循环不可能处理网店交易。我尝试手动将网店URL输入浏览器,一切正常。 我没有写这个系统,我只维护它,所以我宁愿不要对系统进行彻底的改造。
EdiT:我尝试使用javascript和html元进行重定向,但它们只在php停止运行后才能运行
答案 0 :(得分:2)
您问题的直接答案是您需要关闭PHP程序和浏览器之间的HTTP连接。
手动执行此操作是通过发送以下两个标题来实现的:
Connection: close
Content-Length: n (n = size of output in bytes )
...然后刷新输出缓存。
代码看起来像这样:
// send headers to tell the browser to close the connection
header("Content-Length: $contentSize");
header('Connection: close');
// flush all output
ob_end_flush();
ob_flush();
flush();
// .... PHP code can now continue without the browser caring about it.
正如您从上面所注意到的,您需要知道您已经发送的输出量有多大 - 这很重要;如果你在这里给它们一个不正确的值,浏览器会反应很差。您可以使用输出缓冲区(ob_start()
,ob_flush()
)并使用ob_get_length()
检查其大小来跟踪它。不理想,但可能是最好的解决方案。当然,如果您所做的一切都是重定向,那么您可能不会向正文输出任何内容,在这种情况下,只需给出大小为零。
...然而
我会警告不要这样做。这里的问题是,如果程序有一个错误导致它永远不会停止运行或进入无限循环等,那么这样做会使这种错误非常难以追踪。在您的服务器开始减速或拒绝连接之前,您可能甚至都不知道它。
我建议你在完全独立的流程线程中处理长期处理会好得多。我这样做的方法是使用从cron-job中触发的一个小的短期PHP程序来进行轮询。这将在幕后设定的时间间隔内反复运行程序,而不与最终用户或其浏览器连接。
答案 1 :(得分:0)
如果网上商店的API允许你发送一个回调网址,你应该使用一个回调网址,并在那里成功后运行代码而不是在你的服务器上保持一个可能永远不会终止的进程循环。如果回调网址不可用,那么cron-job是可行的方法,它使用一个进程进行所有检查,而不是每个尚未终止的事务都有一个线程。