官方提供的例子,一次执行多个连接,然后阻塞所有链接完成取内容,整个过程是阻塞的。
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 | <?php // 创建单个cURL资源 $ch1 = curl_init(); $ch2 = curl_init(); // 设置URL和相应的选项 curl_setopt( $ch1 , CURLOPT_HEADER, 0); curl_setopt( $ch1 , CURLOPT_RETURNTRANSFER, 1); curl_setopt( $ch2 , CURLOPT_HEADER, 0); curl_setopt( $ch2 , CURLOPT_RETURNTRANSFER, 1); // 创建批处理cURL句柄 $mh = curl_multi_init(); // 增加单个句柄到批处理 curl_multi_add_handle( $mh , $ch1 ); curl_multi_add_handle( $mh , $ch2 ); $active = null; // 执行批处理句柄,循环任务直到全部执行,不等待返回结果 do { $mrc = curl_multi_exec( $mh , $active ); } while ( $mrc == CURLM_CALL_MULTI_PERFORM); //循环判断任务是否执行完成 while ( $active && $mrc == CURLM_OK) { //阻塞等待cURL批处理中的活动连接,失败时返回-1,不等于-1代表还有活动连接 if (curl_multi_select( $mh ) != -1) { //有活动连接时继续执行批处理句柄 do { $mrc = curl_multi_exec( $mh , $active ); } while ( $mrc == CURLM_CALL_MULTI_PERFORM); } } //获取单个URL返回的内容 var_dump(curl_multi_getcontent( $ch1 )); // 关闭全部句柄 curl_multi_remove_handle( $mh , $ch1 ); curl_multi_remove_handle( $mh , $ch2 ); curl_multi_close( $mh ); ?> |
非阻塞实现http://code.google.com/p/rolling-curl/,不过在循环时是根据curl_multi_exec返回的运行状态判断的,大量链接时经常没完成就跳出,修改了下根据循环的队列是否完成来判断。
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 | <?php $isruning = 1; do { //执行句柄内所有连接,包括后来新加入的连接 do { $execrun = curl_multi_exec( $master , $running ); } while ( $execrun == CURLM_CALL_MULTI_PERFORM); //while (($execrun = curl_multi_exec($master, $running)) == CURLM_CALL_MULTI_PERFORM) ; //if ($execrun != CURLM_OK) //break; //有连接返回立即处理,并加入新的连接 while ( $done = curl_multi_info_read( $master )) { //获取返回的信息 $info = curl_getinfo( $done [ 'handle' ]); $output = curl_multi_getcontent( $done [ 'handle' ]); //发送返回信息到回调函数 $callback = $this ->callback; if ( is_callable ( $callback )) { //获取返回信息的句柄 $key = (string) $done [ 'handle' ]; //根据请求映射是哪个请求返回的信息 $request = $this ->requests[ $this ->requestMap[ $key ]]; unset( $this ->requestMap[ $key ]); call_user_func( $callback , $output , $info , $request ); } //判断队列内的连接是否用完 if ( $i < sizeof( $this ->requests) && isset( $this ->requests[ $i ]) && $i < count ( $this ->requests)) { $ch = curl_init(); $options = $this ->get_options( $this ->requests[ $i ]); curl_setopt_array( $ch , $options ); //增加新的连接 curl_multi_add_handle( $master , $ch ); //添加到request Maps,用于返回信息时根据handle找到相应连接 $key = (string) $ch ; $this ->requestMap[ $key ] = $i ; $i ++; } else { //循环结束 $isruning = 0; } //删除完成的句柄 curl_multi_remove_handle( $master , $done [ 'handle' ]); } // Block for data in / output; error handling is done by curl_multi_exec if ( $running ) curl_multi_select( $master , $this ->timeout); } while ( $isruning ); ?> |