php fsockopen 异步请求

2020-7-29 流沙 PHP

项目针对大数据量的脚本, 需要异步请求


代码仅供参考, 自行测试


注意协议和端口的设置


参考代码:


Get异步请求


//异步Get请求
    public static function asyncGet($url, $param=''){
        $host = parse_url($url, PHP_URL_HOST);

        $port = 80;
        $errno = '';
        $errstr = '';
        $timeout = 30;
        if(!empty($param)){
            $url = $url.'?'.http_build_query($param);
        }

        //区分请求类型
        //注意端口和协议的处理
        $urlInfo = parse_url($url);
        switch ($urlInfo['scheme']) {
            case 'https':
                $scheme = 'ssl://';//'tls://';  //如使用HTTPS则使用SSL协议
                $port = 443;
                break;
            case 'http':
            default:
                $scheme = '';  //默认为 tcp://
        }

        // create connect
        $fp = fsockopen($scheme.$host, $port, $errno, $errstr, $timeout);
        if(!$fp){
            return false;
        }

        // send request
        $out = "GET ${url} HTTP/1.1\r\n";
        $out .= "Host:${host}\r\n";
        $out .= "Connection:close\r\n\r\n";
        fwrite($fp, $out);

        //忽略执行结果;否则等待返回结果
        //if(APP_DEBUG === true){
        if(false){
            $ret = '';
            while (!feof($fp)) {
                $ret .= fgets($fp, 128);
            }
        }

        usleep(20000); //fwrite之后马上执行fclose,nginx会直接返回499
        fclose($fp);
    }



POST异步请求


/**
     * 使用fsockopen实现 post 异步请求
     * @param $url 请求地址
     * @param array $params 请求参数
     * @param bool $debug 是否忽略执行结果,默认忽略
     * @return bool
     */
    public function fsockopenPostRequest($url, $params = array(), $debug = false)
    {
        $urlInfo = parse_url($url);
        $host = $urlInfo['host'];
        $path = isset($urlInfo['path']) ? $urlInfo['path'] : '/'; //路径
        $port = isset($urlInfo['port']) ? $urlInfo['port'] : '80'; //端口号
        $data = isset($params) ? http_build_query($params) : '';
        switch ($urlInfo['scheme']) {
            case 'https':
                $scheme = 'tls://';
                break;
            case 'http':
            default:
                $scheme = '';
        }

        $errno = 0;
        $errstr = '';
        $timeout = 5;
        //用fsockopen()尝试连接
        $fp = fsockopen($scheme . $host, $port, $errno, $errstr, $timeout);

        if (!$fp) {
//            echo "$errstr ($errno)<br />\n"; //没有连接
            return false;
        } else {
            $out = "POST " . $path . " HTTP/1.1\r\n";
            $out .= "Host:" . $host . "\r\n";
            $out .= "Content-type:application/x-www-form-urlencoded\r\n";
            $out .= "Content-length:" . strlen($data) . "\r\n";
            $out .= "Connection:close\r\n\r\n";
            $out .= $data;

            fwrite($fp, $out);
            if ($debug) {
                while (!feof($fp)) {
                    echo fgets($fp, 128);
                }
            }
            fclose($fp);
        }
    }




发表评论:

Powered by 流沙团

备案号:鄂ICP备15017378号-1