长时间执行的任务不适合放在PHP中执行应当放在任务调度系统或消息系统中由后台程序去执行,但是有时候还是需要在PHP中执行下长时间的任务 ,并且客户端不需要返回值。实现的思路大体如下:首先客户端发起一个不需要等待返回的请求,服务器端则需要忽略请求中断和执行时间,以免中途退出。
当有请求到达时,服务器端执行任务,在这里会产生一个文件。服务器端文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | <?php //ob_start(); //header('Content-Type:text/html;charset=utf-8'); //header('Connection:close'); //flush(); ignore_user_abort(true); //忽略客户端连接中断 set_time_limit(0); //忽略页面执行超时 //Todo:do something here sleep(10); fopen (dirname( __FILE__ ). '\\' .time(), "w" ); [/php] 1.使用<a href= "http://php.net/manual/en/function.fsockopen.php" > fsockopen </a>来请求服务端执行任务,该方法需要自己拼凑header,包括参数等 <?php function triggerRequest( $url , $post_data = array (), $cookie = array ()){ $method = "GET" ; //可以通过POST或者GET传递一些参数给要触发的脚本 $url_array = parse_url ( $url ); //获取URL信息,以便平凑HTTP HEADER $port = isset( $url_array [ 'port' ])? $url_array [ 'port' ] : 80; $fp = fsockopen ( $url_array [ 'host' ], $port , $errno , $errstr , 30); if (! $fp ){ return FALSE; } $getPath = $url_array [ 'path' ] . "?" . $url_array [ 'query' ]; if (! empty ( $post_data )){ $method = "POST" ; } $header = $method . " " . $getPath ; $header .= " HTTP/1.1\r\n" ; $header .= "Host: " . $url_array [ 'host' ] . "\r\n " ; //HTTP 1.1 Host域不能省略 $header .= "Connection:Close\r\n\r\n" ; if (! empty ( $cookie )){ $_cookie = strval (NULL); foreach ( $cookie as $k =--> $v ){ $_cookie .= $k . "=" . $v . "; " ; } $cookie_str = "Cookie: " . base64_encode ( $_cookie ) . " \r\n" ; //传递Cookie $header .= $cookie_str ; } if (! empty ( $post_data )){ $_post = strval (NULL); foreach ( $post_data as $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 ); fclose( $fp ); return true; } triggerRequest( $url ); |
2.使用curl来发起请求,可以方便的设置传递参数,cookie等,比fsockopen简洁许多,需要安装php_curl扩展
1 2 3 4 5 6 7 8 9 | <?php $ch = curl_init(); $data = array ( 'param' => '1' ); curl_setopt( $ch , CURLOPT_URL, 'http://127.0.0.1/learn/asyn/server.php' ); curl_setopt( $ch , CURLOPT_POST, 1); curl_setopt( $ch , CURLOPT_POSTFIELDS, $data ); curl_setopt( $ch , CURLOPT_TIMEOUT, 1); //1秒后立即执行 curl_exec( $ch ); curl_close( $ch ); |
也可以采用popen,ajax发起请求,详见参考链接。
参考链接
fsockopen函数用法
使用fscok实现异步调用PHP
PHP实现异步调用方法研究
说说php的异步请求
php curl常用的5个例子