PHP实现多个异步的http请求

摘自: PHP手册

以前感觉PHP里没法同时执行多个http请求,这次看手册不小心发现了这种用法,就是通过设置非阻塞模式来实现异步的http请求,对于单个脚本中要尽快执行完大量的http请求的应用来讲是非常适合的。

<?php
function multiHTTP ($urlArr) {
    
$sockets = Array(); // socket array!
    
$urlInfo = Array(); // info arr
    
$sumDone 0;
    
$ret = Array();
    
$errno  = Array();
    
$errstr  = Array();
    foreach (
$urlArr as $key=>$url) {
        
$urlInfo[$key] = parse_url($urlArr[$key]);
        
$urlInfo[$key][port] = ($urlInfo[$key][port]) ? $urlInfo[$key][port] : 80;
        
$urlInfo[$key][path] = ($urlInfo[$key][path]) ? $urlInfo[$key][path] : "/";
        
$sockets[$key] = @fsockopen($urlInfo[$key][host], $urlInfo[$key][port], $errno[$key], $errstr[$key], 30);
        if(!
$sockets[$key]){
            
$ret[$key][‘result’] = false;
            
$ret[$key][‘error’]  = $errstr[$key];
            
$ret[$key][‘done’] = 1;
            
$sumDone++;
            continue;
        }
        
$ret[$key][‘result’] = true;
        
socket_set_blocking($sockets[$key],false);
        
$query = ($urlInfo[$key][query]) ? "?" $urlInfo[$key][query] : "";
        
fputs($sockets[$key],"GET " $urlInfo[$key][path] . "$query HTTP/1.0\r\nHost: " .
                        
$urlInfo[$key][host] . "\r\n\r\n");
    }
    
// ok read the data from each one
    
$done false;
    while (!
$done) {
        foreach (
$urlArr as $key=>$url) {
            if(
$ret[$key][‘done’] == 1) continue;
            if (!
feof($sockets[$key])) {
                if (
$ret[$key][‘data’]) {
                        
$ret[$key][‘data’] .= fgets($sockets[$key],1024);
                } else {
                        
$ret[$key][‘data’] = fgets($sockets[$key],1024);
                }
            } else {
                
$ret[$key][‘done’] = 1;
                
$sumDone++;
                
fclose($sockets[$key]);
            }
        }
        
$done = ($sumDone == count($urlArr));
    }
    foreach(
$ret as $key=>$item){
        
$ret[$key][‘data’] = substr($item[‘data’],strpos($item[‘data’],"\r\n\r\n") + 4);
    }
    return 
$ret;
}
?>

留下评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据