异步调用:fscok实现异步调用PHP



Web服务器执行个脚本可能几毫秒就完成也可能几分钟都完不成如果执行缓慢用户可能没有耐心等下去就关闭浏览器了
而有时候我们更本不关心这些耗时脚本执行结果但却还要等他执行完返回才能继续下
那么有没有什么办法只是简单触发这些耗时脚本然后就继续下让这些耗时脚本在服务端慢慢执行?

接下来我将使用fscokopen来实现这功能

PHP是支持编程就是fsockopen在以前做CMS时候我也曾经用过它做过smtp发信
fscokopen返回个到远程主机连接句柄你可以像使用fopen返回句柄对她进行写fwrite读取fgets,fread等操作

我们异步PHP主要想要效果就是触发个PHP脚本然后立即返回留它在服务器端慢慢执行前面我也写过篇文章讨论过这个问题

那么我们就可以使用fsockopen连接到本地服务器触发脚本执行然后立即返回不等待脚本执行完成

functiontriggerRequest($url,$post_data=.gif' />,$cookie=.gif' />)...{
$method=\"GET\";//可以通过POST或者GET传递些参数给要触发脚本
$url_.gif' />=parse_url($url);//获取URL信息以便平凑HTTPHEADER
$port=is($url_.gif' />[’port’])?$url_.gif' />[’port’]:80;

$fp=fsockopen($url_.gif' />[’host’],$port,$errno,$errstr,30);
(!$fp)...{
FALSE;
}
$getPath=$url_.gif' />[’path’].\"?\".$url_.gif' />[’query’];
(!empty($post_data))...{
$method=\"POST\";
}
$header=$method.\"\".$getPath;
$header.=\"HTTP/1.1\\r\\n\";
$header.=\"Host:\".$url_.gif' />[’host’].\"\\r\\n\";//HTTP1.1Host域不能省略
/**//*以下头信息域可以省略
$header.=\"User-Agent:Mozilla/5.0(Windows;U;WindowsNT5.1;en-US;rv:1.8.1.13)Gecko/20080311Firefox/2.0.0.13\\r\\n\";
$header.=\"Accept:text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,q=0.5\\r\\n\";
$header.=\"Accept-Language:en-us,en;q=0.5\";
$header.=\"Accept-Encoding:gzip,deflate\\r\\n\";
*/

$header.=\"Connection:Close\\r\\n\"; [Page]
(!empty($cookie))...{
$_cookie=strval(NULL);
foreach($cookieas$k=>$v)...{
$_cookie.=$k.\"=\".$v.\";\";
}
$cookie_str=\"Cookie:\".base64_encode($_cookie).\"\\r\\n\";//传递Cookie
$header.=$cookie_str;
}
(!empty($post_data))...{
$_post=strval(NULL);


foreach($post_dataas$k=>$v)...{
$_post.=$k.\"=\".$v.\"&\";
}
$post_str=\"Content-Type:application/x-www-form-urlencoded\\r\\n\";//POST数据
$post_str.=\"Content-Length:\".strlen($_post).\"\\r\\n\";//POST数据长度
$post_str.=$_post.\"\\r\\n\\r\\n\";//传递POST数据
$header.=$post_str;
}
fwrite($fp,$header);
//echofread($fp,1024);//我们不关心服务器返回
fclose($fp);
true;
}
现在就可以通过这个来触发个PHP脚本执行然后就会返回我们就可以接着执行下步操作了

还有个问题就是当客户端断开连接以后也就是triggerRequest发送请求后立即关闭了连接那么可能会引起服务器端正在执行脚本退出
在PHP内部系统维护着连接状态其状态有 3种可能情况:

*0-NORMAL(正常)
*1-ABORTED(异常退出)
*2-TIMEOUT(超时)

当PHP脚本正常地运行NORMAL状态时连接为有效当客户端中断连接时ABORTED状态标记将会被打开远程客户端连接中断通常是由用户点击STOP按钮导致当连接时间超过PHP时限(请参阅_time_limit)时TIMEOUT状态标记将被打开 [Page]

可以决定脚本是否需要在客户端中断连接时退出有时候让脚本完整地运行会带来很多方便即使没有远程浏览器接受脚本输出默认情况是当远程客户端连接中断时脚本将会退出该处理过程可由php.iniignore_user_abort或由Apache.conf设置中对应“php_valueignore_user_abort”以及ignore_user_abort来控制如果没有告诉PHP忽略用户中断脚本将会被中断除非通过register_shutdown_function设置了关闭触发通过该关闭触发当远程用户点击STOP按钮后脚本再次尝试输出数据时PHP将会检测到连接已被中断关闭触发

脚本也有可能被内置脚本计时器中断默认超时限制为30秒这个值可以通过设置php.inimax_execution_time或Apache.conf设置中对应“php_valuemax_execution_time”参数或者_time_limit来更改当计数器超时时候脚本将会类似于以上连接中断情况退出先前被注册过关闭触发也将在这时被执行在该关闭触发可以通过connection_status来检查超时是否导致关闭触发如果超时导致了关闭触发将返回2

需要注意点是ABORTED和TIMEOUT状态可以同时有效这在告诉PHP忽略用户退出操作时是可能PHP将仍然注意用户已经中断了连接但脚本仍然在运行情况如果到了运行时间限制脚本将被退出设置过关闭触发也将被执行在这时会发现connection_status返回3

所以还在要触发脚本中指明:
ignore_user_abort(TRUE);//如果客户端断开连接不会引起脚本abort.
_time_limit(0);//取消脚本执行延时上限或者也可以使用:register_shutdown_function(callbackfuction[,parameters]);//注册脚本退出时执行
Tags:  php函数调用 asp调用php php调用 异步调用

延伸阅读

最新评论

发表评论