1、curl_multi方法
当需要多线程的时候,可以用curl_multi一次性请求多个操作来完成,但curl走的是网络通信,效率与可靠性就比较差了的。
php" id="highlighter_277535">
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
function main(){
$sql = "select waybill_id,order_id from waybill where status>40 order by update_time desc limit 10 " ;
$data = Yii::app()->db->createCommand( $sql )->queryAll(); //yii 框架格式
foreach ( $data as $k => $v ) {
if ( $k % 2 == 0) { //偶数发一个网址
$send_data [ $k ][ 'url' ] = '' ;
$send_data [ $k ][ 'body' ] = $v [ 'waybill_id' ];
} else { //奇数发送另外一个网址
$send_data [ $k ][ 'url' ] = ' http://www.abc.com ' ;
$send_data [ $k ][ 'body' ]= array ( $v [ 'order_id' ] => array ( 'extra' => 16));
}
}
$back_data =sendMulitRequest( $send_data );
var_dump( $back_data );
}
function sendMulitRequest( $send_data ){
$params = array ();
$curl = $text = array ();
$handle = curl_multi_init();
foreach ( $data as $k => $v ) {
if ( empty ( $v [ 'url' ])) {
$v [ 'url' ] = " http://www.xxx.com " ; // if url is empty ,set defalut url
}
$reqBody = json_encode( $v [ 'body' ]);
$reqStream = array (
'body' => $reqBody ,
);
$encRequest = base64_encode (json_encode( $reqStream ));
$params [ 'data' ] = $encRequest ;
$curl [ $k ] = curl_init();
curl_setopt( $curl [ $k ], CURLOPT_URL, $v [ 'url' ]);
curl_setopt( $curl [ $k ], CURLOPT_POST, TRUE);
curl_setopt( $curl [ $k ], CURLOPT_HEADER, 0);
curl_setopt( $curl [ $k ], CURLOPT_POSTFIELDS, http_build_query( $params ));
curl_setopt( $curl [ $k ], CURLOPT_RETURNTRANSFER, 1);
curl_multi_add_handle( $handle , $curl [ $k ]);
}
$active = null;
do {
$mrc = curl_multi_exec( $handle , $active );
} while ( $mrc == CURLM_CALL_MULTI_PERFORM);
while ( $active && $mrc == CURLM_OK) {
if (curl_multi_select( $handle ) != -1) {
do {
$mrc = curl_multi_exec( $handle , $active );
} while ( $mrc == CURLM_CALL_MULTI_PERFORM);
}
}
foreach ( $curl as $k => $v ) {
if (curl_error( $curl [ $k ]) == "" ) {
$text [ $k ] = (string) curl_multi_getcontent( $curl [ $k ]);
}
curl_multi_remove_handle( $handle , $curl [ $k ]);
curl_close( $curl [ $k ]);
}
curl_multi_close( $handle );
return $text ;
}
|
2、通过stream_socket_client 方式
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
58
59
60
61
62
|
function sendStream() {
$english_format_number = number_format( $number , 4, '.' , '' );
echo $english_format_number ;
exit ();
$timeout = 10;
$result = array ();
$sockets = array ();
$convenient_read_block = 8192;
$host = "test.local.com" ;
$sql = "select waybill_id,order_id from xm_waybill where status>40 order by update_time desc limit 1 " ;
$data = Yii::app()->db->createCommand( $sql )->queryAll();
$id = 0;
foreach ( $data as $k => $v ) {
if ( $k % 2 == 0) {
$send_data [ $k ][ 'body' ] = NoticeOrder::getSendData( $v [ 'waybill_id' ]);
} else {
$send_data [ $k ][ 'body' ] = array ( $v [ 'order_id' ] => array ( 'extra' => 16));
}
$data = json_encode( $send_data [ $k ][ 'body' ]);
$s = stream_socket_client( $host . ":80" , $errno , $errstr , $timeout , STREAM_CLIENT_ASYNC_CONNECT | STREAM_CLIENT_CONNECT);
if ( $s ) {
$sockets [ $id ++] = $s ;
$http_message = "GET /php/test.php?data=" . $data . " HTTP/1.0\r\nHost:" . $host . "\r\n\r\n" ;
fwrite( $s , $http_message );
} else {
echo "Stream " . $id . " failed to open correctly." ;
}
}
while ( count ( $sockets )) {
$read = $sockets ;
stream_select( $read , $w = null, $e = null, $timeout );
if ( count ( $read )) {
/* stream_select generally shuffles $read, so we need to
compute from which socket(s) we're reading. */
foreach ( $read as $r ) {
$id = array_search ( $r , $sockets );
$data = fread ( $r , $convenient_read_block );
if ( strlen ( $data ) == 0) {
echo "Stream " . $id . " closes at " . date ( 'h:i:s' ) . ".<br> " ;
fclose( $r );
unset( $sockets [ $id ]);
} else {
$result [ $id ] = $data ;
}
}
} else {
/* A time-out means that *all* streams have failed
to receive a response. */
echo "Time-out!\n" ;
break ;
}
}
print_r( $result );
}
|
3、通过多进程代替多线程
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
|
function daemon( $func_name , $args , $number ){
while (true){
$pid =pcntl_fork();
if ( $pid ==-1){
echo "fork process fail" ;
exit ();
} elseif ( $pid ){ //创建的子进程
static $num =0;
$num ++;
if ( $num >= $number ){
//当进程数量达到一定数量时候,就对子进程进行回收。
pcntl_wait( $status );
$num --;
}
} else { //为0 则代表是子进程创建的,则直接进入工作状态
if (function_exists( $func_name )){
while (true) {
$ppid =posix_getpid();
var_dump( $ppid );
call_user_func_array( $func_name , $args );
sleep(2);
}
} else {
echo "function is not exists" ;
}
exit ();
}
}
}
function worker( $args ){
//do something
}
daemon( 'worker' , array (1),2);
|
以上就是为大家分享的三种php实现多线程类似的方法,希望对大家的学习有所帮助。