14
回答
分享一个http类 -- 两个凡是
百度AI开发者大赛带你边学边开发,赢100万奖金,加群:418589053   
<?php defined('SYSPATH') or die('No direct script access.');
/**
 * Provides http server communications options using [Stream]
 * Mainly used to communiated with http
 * Add Support HTTP/1.1 by Default
 * Only Support Connection Close Mode
 *
 * @author     anthony Chen
 */
class Http {

	public static $allow_self_signed = true;
	public static $non_blocking = false;
	/**
	 * @var  array  default header options
	 */
	public static $default_options = array (
			'User-Agent'=> 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit /538.36 (KHTML, like Gecko) Pexcel/6.998',
			'Connection'=> 'Close' //Need to close the request every time for HTTP 1.1
		);

	/**
	 * return Array lines of headers
	 * Overwrite by $options
	 *
	 * @param Array $options, key value pairs of Header options
	 * 
	 * @return Array,Array line of headers
	 */
	private static function getHeaders($options){
		if ($options === NULL) {
			// Use default options
			$options = self::$default_options;
		} else {
			//Merge the $options with $default_options, if the value set in $options,
			//Value in $default_options will be overwrite
			$options =$options + self::$default_options ;
		}

		$headers = array();
		foreach($options as $k=>$v){
			$headers[] = $k.': '.$v;
		}

		return $headers;
	}

	/**
	 * Returns the output of a http URL. 
	 * may be used.
	 *
	 * @param   string   http base URL or FULL url
	 * @param   array    Header options
	 * @param   array $data Get Param
	 * @param   array &$rr_headers,Request Response headers
	 * 		    if Assigned,the response header will be populated
	 * 			If ['fingerprint'] is set, then finger is checked in SSL Context
	 * 			If ['ignore_errors'] is set, then ignore http error code other than 200
	 *
	 * @return  string, Raw String of Http body
	 */
	public static function get($url, array $options = NULL,$data = NULL,&$rr_headers = NULL) {
		$headers = self::getHeaders($options);
		$params = ['http' => [
			'method' => 'GET',
			//Defautl HTTP 1.1 and with Connection Close
			'protocol_version'=>'1.1',
			//'Connection'=> 'Close' //Need to close the request every time for HTTP 1.1
		]];

		if(Arr::get($rr_headers,'ignore_errors') == true){
			$params['http']['ignore_errors'] = true;
		}

		$params['http']['header'] = $headers;

		if($data){
			$url .= '?'.http_build_query($data); 
		}
		$ctx = stream_context_create($params);
		if(self::$allow_self_signed == true){
			stream_context_set_option($ctx,["ssl"=>["allow_self_signed"=>true,"verify_peer_name"=>false,"verify_peer"=>false]]);
			$_finger = Arr::get($rr_headers,'fingerprint');
			if($_finger){
				stream_context_set_option($ctx,["ssl"=>["peer_fingerprint"=>$_finger]]);
			}
		}

		$fp = fopen($url, 'rb', false, $ctx);
		if (!$fp) {
			throw new Exception("Connection failed: $url");
		}

		if(self::$non_blocking == TRUE){
			stream_set_blocking($fp,0);
		}

		if($rr_headers !== NULL){
			$rr_headers = stream_get_meta_data($fp);
		}

		$response = stream_get_contents($fp);
		if ($response === false) {
			throw new Exception("Reading data Failed: $url");
		}
		fclose($fp);
		return $response;
	}

	/**
	 * Post with request options and data 
	 *
	 * @param String url, FULL url
	 * @param Array $options , key=>value pairs array
	 * @param Array $data ,Post Data pairs
	 * @param   array &$rr_headers,Request Response headers
	 * 		    if Assigned,the response header will be populated
	 * 			If ['fingerprint'] is set, then finger is checked in SSL Context
	 * 			If ['ignore_errors'] is set, then ignore http error code other than 200
	 * @return  string, Raw String of Http body
	 */
	public static function post($url,  $options = null,$data=NULL,&$rr_headers = NULL) {
		//Restricted the Form formate
		if(is_array($data)){
			$data = http_build_query($data);
		}

		$options['Content-type'] = Arr::get($options,'Content-type','application/x-www-form-urlencoded');
		$options['Content-Length'] =Arr::get($options,'Content-Length',strlen($data));

		$params = ['http' => [
			'method' => 'POST',
			'protocol_version'=>'1.1',
			//'Connection'=> 'Close', //Need to close the request every time for HTTP 1.1
			//'ignore_errors'=>true,
			'content' => $data
		]];

		if(Arr::get($rr_headers,'ignore_errors') == true){
			$params['http']['ignore_errors'] = true;
		}

		$headers = self::getHeaders($options);
		$params['http']['header'] = $headers;

		$ctx = stream_context_create($params);
		if(self::$allow_self_signed == true){
			stream_context_set_option($ctx,["ssl"=>["allow_self_signed"=>true,"verify_peer_name"=>false,"verify_peer"=>false]]);
			$_finger = Arr::get($rr_headers,'fingerprint');
			if($_finger){
				stream_context_set_option($ctx,["ssl"=>["peer_fingerprint"=>$_finger]]);
			}
		}

		$fp = fopen($url, 'rb', false, $ctx);
		if (!$fp) {
			throw new Exception("Connection Failed: $url ");
		}

		if(self::$non_blocking == TRUE){
			stream_set_blocking($fp,0);
		}

		if($rr_headers !== NULL){
			$rr_headers = stream_get_meta_data($fp);
		}

		$response = stream_get_contents($fp);
		if ($response === false) {
			throw new Exception("Reading data failed: $url");
		}
		fclose($fp);
		return $response;
	} 

	/**
	 * Inflate zipped content
	 *
	 * @param String $_content, gzipped content
	 *
	 * @return String, Inflated content
	 */
	public static function inflate($_content){
		//deflate add 10 charaters before inflate format and 8 charaters checksum append
		//gzdecode is not availible for ALL PHP even gzencode is avalible
		$_content = substr($_content, 10,-8); 
		return gzinflate($_content);

	}

	/**
	 * Check if the reponse content is zipped from response header
	 *
	 * @param Array $_response_header, Response header captured from get/post
	 *
	 * @return Boolean, True for zipped contented
	 */
	public static function isZipped($_response_header){
		if (preg_grep('/^Content-Encoding:\s*gzip/i',$_response_header['wrapper_data'])){
			return TRUE;
		}else{
			return False;
		}
	}

	/**
	 * Parse response headers into K V data
	 *
	 * @param Array $headers, wrapper data return from http request
	 *
	 * @return Array , the parsed headers of http
	 */
	public static function parseHeaders( $_response_header ) {
		$headers = Arr::get($_response_header,'wrapper_data',[]);
		$head = array();
		foreach( $headers as $k=>$v )
		{
			$t = explode( ':', $v, 2 );
			if( isset( $t[1] ) )
				$head[ trim($t[0]) ] = trim( $t[1] );
			else
			{
				$head[] = $v;
				if( preg_match( "#HTTP/[0-9\.]+\s+([0-9]+)#",$v, $out ) )
					$head['reponse_code'] = intval($out[1]);
			}
		}
		return $head;
	}
} // End http



PHP
举报
宏哥
发帖于2年前 14回/940阅

以下是话题补充:

  • @宏哥 :让curl这种库去死吧, 将一件事做到极致是一种孤独的存在,就像两个凡是 (2年前)
共有14个评论 最后回答: 2年前

不了解 PHP,内容不好说,但是可以从代码格式上找点存在感

// 1. 参数间有时有空格,有时没有
public static function post($url,  $options = null,$data=NULL,&$rr_headers = NULL) {

// 2. )和{之间有时有空格,有时没有

// 3. 命名规则混乱
self::getHeaders($options);
stream_set_blocking($fp,0);

// 4. TRUE, False, false 混乱使用

// 5. 片段优化
// 不必要的 if else
public static function isZipped($_response_header){
    if (preg_grep('/^Content-Encoding:\s*gzip/i',$_response_header['wrapper_data'])){
        return TRUE;
    }else{
        return False;
    }
}

public static function isZipped($_response_header){
    return preg_grep('/^Content-Encoding:\s*gzip/i',$_response_header['wrapper_data']));
}

// 6. 空白行也小有瑕疵
if($rr_headers !== NULL){
    $rr_headers = stream_get_meta_data($fp);
}

$response = stream_get_contents($fp);
if ($response === false) {
    throw new Exception("Reading data failed: $url");
}
fclose($fp);
return $response;

// 7. 注释 param 后面的对齐不统一
/**
 * return Array lines of headers
 * Overwrite by $options
 *
 * @param Array $options, key value pairs of Header options
 * 
 * @return Array,Array line of headers
 */

 /**
  * Returns the output of a http URL. 
  * may be used.
  *
  * @param   string   http base URL or FULL url
  * @param   array    Header options
  * @param   array $data Get Param
  * @param   array &$rr_headers,Request Response headers
  *          if Assigned,the response header will be populated
  *          If ['fingerprint'] is set, then finger is checked in SSL Context
  *          If ['ignore_errors'] is set, then ignore http error code other than 200
  *
  * @return  string, Raw String of Http body
  */



--- 共有 4 条评论 ---
公孙二狗回复 @宏哥 : 好谦虚啊,我也就是来找抽的 ^_^ 2年前 回复
宏哥回复 @公孙二狗 : 已经针对做了修改,感谢指出 2年前 回复
大止刀口回复 @公孙二狗 : 大部分赞同。不过第3点是由于PHP里只有面向对象部分用驼峰(self::getHeaders)而非面向对象部分都用下划线(stream_set_blocking)。PHP标准库应该也是这样的命名风格。 2年前 回复
公孙二狗"将一件事做到极致是一种孤独的存在,就像两个凡是" 这么多小瑕疵的地方,绝对不是做到极致的现象! 2年前 回复

我这是在作死

/**
 * Provides http server communications options using [Stream]
 * Mainly used to communiated with http
 * Add Support HTTP/1.1 by Default
 * Only Support Connection Close Mode
 *
 * @author     anthony Chen
 */

communication 有复数 communications 吗?
used to communiated? 不是 communicate?
Only Support Connection Close Mode 能读的通吗?



来来来,我也分享一个:
<?php
/**
 * Http.php.
 *
 * Part of Overtrue\Wechat.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @author    overtrue <i@overtrue.me>
 * @copyright 2015 overtrue <i@overtrue.me>
 *
 * @link      https://github.com/overtrue
 * @link      http://overtrue.me
 */
/**
 * Http请求类.
 *
 * from https://github.com/dsyph3r/curl-php/blob/master/lib/Network/Curl/Curl.php
 */
class Http
{
    /**
     * Constants for available HTTP methods.
     */
    const GET = 'GET';
    const POST = 'POST';
    const PUT = 'PUT';
    const PATCH = 'PATCH';
    const DELETE = 'DELETE';
    /**
     * CURL句柄.
     *
     * @var resource handle
     */
    protected $curl;
    /**
     * Create the cURL resource.
     */
    public function __construct()
    {
        $this->curl = curl_init();
    }
    /**
     * Clean up the cURL handle.
     */
    public function __destruct()
    {
        if (is_resource($this->curl)) {
            curl_close($this->curl);
        }
    }
    /**
     * Get the cURL handle.
     *
     * @return resource cURL handle
     */
    public function getCurl()
    {
        return $this->curl;
    }
    /**
     * Make a HTTP GET request.
     *
     * @param string $url
     * @param array  $params
     * @param array  $options
     *
     * @return array
     */
    public function get($url, $params = array(), $options = array())
    {
        return $this->request($url, self::GET, $params, $options);
    }
    /**
     * Make a HTTP POST request.
     *
     * @param string $url
     * @param array  $params
     * @param array  $options
     *
     * @return array
     */
    public function post($url, $params = array(), $options = array())
    {
        return $this->request($url, self::POST, $params, $options);
    }
    /**
     * Make a HTTP PUT request.
     *
     * @param string $url
     * @param array  $params
     * @param array  $options
     *
     * @return array
     */
    public function put($url, $params = array(), $options = array())
    {
        return $this->request($url, self::PUT, $params, $options);
    }
    /**
     * Make a HTTP PATCH request.
     *
     * @param string $url
     * @param array  $params
     * @param array  $options
     *
     * @return array
     */
    public function patch($url, $params = array(), $options = array())
    {
        return $this->request($url, self::PATCH, $params, $options);
    }
    /**
     * Make a HTTP DELETE request.
     *
     * @param string $url
     * @param array  $params
     * @param array  $options
     *
     * @return array
     */
    public function delete($url, $params = array(), $options = array())
    {
        return $this->request($url, self::DELETE, $params, $options);
    }
    /**
     * Make a HTTP request.
     *
     * @param string $url
     * @param string $method
     * @param array  $params
     * @param array  $options
     *
     * @return array
     */
    protected function request($url, $method = self::GET, $params = array(), $options = array())
    {
        if ($method === self::GET || $method === self::DELETE) {
            $url .= (stripos($url, '?') ? '&' : '?').http_build_query($params);
            $params = array();
        }
        curl_setopt($this->curl, CURLOPT_HEADER, 1);
        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($this->curl, CURLOPT_URL, $url);
        //使用证书情况
        if (isset($options['sslcert_path']) && isset($options['sslkey_path'])) {
            if (!file_exists($options['sslcert_path']) || !file_exists($options['sslkey_path'])) {
                throw new \Exception('Certfile is not correct');
            }
            //设置证书
            //使用证书:cert 与 key 分别属于两个.pem文件
            curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, true);
            curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, 2);//严格校验
            curl_setopt($this->curl, CURLOPT_SSLCERTTYPE, 'PEM');
            curl_setopt($this->curl, CURLOPT_SSLCERT, $options['sslcert_path']);
            curl_setopt($this->curl, CURLOPT_SSLKEYTYPE, 'PEM');
            curl_setopt($this->curl, CURLOPT_SSLKEY, $options['sslkey_path']);
        } else {
            curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, 0);
            curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, 0);
        }
        // Check for files
        if (isset($options['files']) && count($options['files'])) {
            foreach ($options['files'] as $index => $file) {
                $params[$index] = $this->createCurlFile($file);
            }
            version_compare(PHP_VERSION, '5.5', '<') || curl_setopt($this->curl, CURLOPT_SAFE_UPLOAD, false);
            curl_setopt($this->curl, CURLOPT_POST, 1);
            curl_setopt($this->curl, CURLOPT_POSTFIELDS, $params);
        } else {
            if (isset($options['json'])) {
                $params = JSON::encode($params);
                $options['headers'][] = 'content-type:application/json';
            }
            curl_setopt($this->curl, CURLOPT_POSTFIELDS, $params);
        }
        // Check for custom headers
        if (isset($options['headers']) && count($options['headers'])) {
            curl_setopt($this->curl, CURLOPT_HTTPHEADER, $options['headers']);
        }
        // Check for basic auth
        if (isset($options['auth']['type']) && 'basic' === $options['auth']['type']) {
            curl_setopt($this->curl, CURLOPT_USERPWD, $options['auth']['username'].':'.$options['auth']['password']);
        }
        $response = $this->doCurl();
        // Separate headers and body
        $headerSize = $response['curl_info']['header_size'];
        $header = substr($response['response'], 0, $headerSize);
        $body = substr($response['response'], $headerSize);
        $results = array(
                    'curl_info' => $response['curl_info'],
                    'content_type' => $response['curl_info']['content_type'],
                    'status' => $response['curl_info']['http_code'],
                    'headers' => $this->splitHeaders($header),
                    'data' => $body,
                   );
        return $results;
    }
    /**
     * make cURL file.
     *
     * @param string $filename
     *
     * @return \CURLFile|string
     */
    protected function createCurlFile($filename)
    {
        if (function_exists('curl_file_create')) {
            return curl_file_create($filename);
        }
        return "@$filename;filename=".basename($filename);
    }
    /**
     * Split the HTTP headers.
     *
     * @param string $rawHeaders
     *
     * @return array
     */
    protected function splitHeaders($rawHeaders)
    {
        $headers = array();
        $lines = explode("\n", trim($rawHeaders));
        $headers['HTTP'] = array_shift($lines);
        foreach ($lines as $h) {
            $h = explode(':', $h, 2);
            if (isset($h[1])) {
                $headers[$h[0]] = trim($h[1]);
            }
        }
        return $headers;
    }
    /**
     * Perform the Curl request.
     *
     * @return array
     */
    protected function doCurl()
    {
        $response = curl_exec($this->curl);
        if (curl_errno($this->curl)) {
            throw new \Exception(curl_error($this->curl), 1);
        }
        $curlInfo = curl_getinfo($this->curl);
        $results = array(
                    'curl_info' => $curlInfo,
                    'response' => $response,
                   );
        return $results;
    }
}



引用来自“公孙二狗”的评论

我这是在作死

/**
 * Provides http server communications options using [Stream]
 * Mainly used to communiated with http
 * Add Support HTTP/1.1 by Default
 * Only Support Connection Close Mode
 *
 * @author     anthony Chen
 */

communication 有复数 communications 吗?
used to communiated? 不是 communicate?
Only Support Connection Close Mode 能读的通吗?



注释确实需要修改

引用来自“螃蟹大叔”的评论

来来来,我也分享一个:
<?php
/**
 * Http.php.
 *
 * Part of Overtrue\Wechat.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @author    overtrue <i@overtrue.me>
 * @copyright 2015 overtrue <i@overtrue.me>
 *
 * @link      https://github.com/overtrue
 * @link      http://overtrue.me
 */
/**
 * Http请求类.
 *
 * from https://github.com/dsyph3r/curl-php/blob/master/lib/Network/Curl/Curl.php
 */
class Http
{
    /**
     * Constants for available HTTP methods.
     */
    const GET = 'GET';
    const POST = 'POST';
    const PUT = 'PUT';
    const PATCH = 'PATCH';
    const DELETE = 'DELETE';
    /**
     * CURL句柄.
     *
     * @var resource handle
     */
    protected $curl;
    /**
     * Create the cURL resource.
     */
    public function __construct()
    {
        $this->curl = curl_init();
    }
    /**
     * Clean up the cURL handle.
     */
    public function __destruct()
    {
        if (is_resource($this->curl)) {
            curl_close($this->curl);
        }
    }
    /**
     * Get the cURL handle.
     *
     * @return resource cURL handle
     */
    public function getCurl()
    {
        return $this->curl;
    }
    /**
     * Make a HTTP GET request.
     *
     * @param string $url
     * @param array  $params
     * @param array  $options
     *
     * @return array
     */
    public function get($url, $params = array(), $options = array())
    {
        return $this->request($url, self::GET, $params, $options);
    }
    /**
     * Make a HTTP POST request.
     *
     * @param string $url
     * @param array  $params
     * @param array  $options
     *
     * @return array
     */
    public function post($url, $params = array(), $options = array())
    {
        return $this->request($url, self::POST, $params, $options);
    }
    /**
     * Make a HTTP PUT request.
     *
     * @param string $url
     * @param array  $params
     * @param array  $options
     *
     * @return array
     */
    public function put($url, $params = array(), $options = array())
    {
        return $this->request($url, self::PUT, $params, $options);
    }
    /**
     * Make a HTTP PATCH request.
     *
     * @param string $url
     * @param array  $params
     * @param array  $options
     *
     * @return array
     */
    public function patch($url, $params = array(), $options = array())
    {
        return $this->request($url, self::PATCH, $params, $options);
    }
    /**
     * Make a HTTP DELETE request.
     *
     * @param string $url
     * @param array  $params
     * @param array  $options
     *
     * @return array
     */
    public function delete($url, $params = array(), $options = array())
    {
        return $this->request($url, self::DELETE, $params, $options);
    }
    /**
     * Make a HTTP request.
     *
     * @param string $url
     * @param string $method
     * @param array  $params
     * @param array  $options
     *
     * @return array
     */
    protected function request($url, $method = self::GET, $params = array(), $options = array())
    {
        if ($method === self::GET || $method === self::DELETE) {
            $url .= (stripos($url, '?') ? '&' : '?').http_build_query($params);
            $params = array();
        }
        curl_setopt($this->curl, CURLOPT_HEADER, 1);
        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($this->curl, CURLOPT_URL, $url);
        //使用证书情况
        if (isset($options['sslcert_path']) && isset($options['sslkey_path'])) {
            if (!file_exists($options['sslcert_path']) || !file_exists($options['sslkey_path'])) {
                throw new \Exception('Certfile is not correct');
            }
            //设置证书
            //使用证书:cert 与 key 分别属于两个.pem文件
            curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, true);
            curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, 2);//严格校验
            curl_setopt($this->curl, CURLOPT_SSLCERTTYPE, 'PEM');
            curl_setopt($this->curl, CURLOPT_SSLCERT, $options['sslcert_path']);
            curl_setopt($this->curl, CURLOPT_SSLKEYTYPE, 'PEM');
            curl_setopt($this->curl, CURLOPT_SSLKEY, $options['sslkey_path']);
        } else {
            curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, 0);
            curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, 0);
        }
        // Check for files
        if (isset($options['files']) && count($options['files'])) {
            foreach ($options['files'] as $index => $file) {
                $params[$index] = $this->createCurlFile($file);
            }
            version_compare(PHP_VERSION, '5.5', '<') || curl_setopt($this->curl, CURLOPT_SAFE_UPLOAD, false);
            curl_setopt($this->curl, CURLOPT_POST, 1);
            curl_setopt($this->curl, CURLOPT_POSTFIELDS, $params);
        } else {
            if (isset($options['json'])) {
                $params = JSON::encode($params);
                $options['headers'][] = 'content-type:application/json';
            }
            curl_setopt($this->curl, CURLOPT_POSTFIELDS, $params);
        }
        // Check for custom headers
        if (isset($options['headers']) && count($options['headers'])) {
            curl_setopt($this->curl, CURLOPT_HTTPHEADER, $options['headers']);
        }
        // Check for basic auth
        if (isset($options['auth']['type']) && 'basic' === $options['auth']['type']) {
            curl_setopt($this->curl, CURLOPT_USERPWD, $options['auth']['username'].':'.$options['auth']['password']);
        }
        $response = $this->doCurl();
        // Separate headers and body
        $headerSize = $response['curl_info']['header_size'];
        $header = substr($response['response'], 0, $headerSize);
        $body = substr($response['response'], $headerSize);
        $results = array(
                    'curl_info' => $response['curl_info'],
                    'content_type' => $response['curl_info']['content_type'],
                    'status' => $response['curl_info']['http_code'],
                    'headers' => $this->splitHeaders($header),
                    'data' => $body,
                   );
        return $results;
    }
    /**
     * make cURL file.
     *
     * @param string $filename
     *
     * @return \CURLFile|string
     */
    protected function createCurlFile($filename)
    {
        if (function_exists('curl_file_create')) {
            return curl_file_create($filename);
        }
        return "@$filename;filename=".basename($filename);
    }
    /**
     * Split the HTTP headers.
     *
     * @param string $rawHeaders
     *
     * @return array
     */
    protected function splitHeaders($rawHeaders)
    {
        $headers = array();
        $lines = explode("\n", trim($rawHeaders));
        $headers['HTTP'] = array_shift($lines);
        foreach ($lines as $h) {
            $h = explode(':', $h, 2);
            if (isset($h[1])) {
                $headers[$h[0]] = trim($h[1]);
            }
        }
        return $headers;
    }
    /**
     * Perform the Curl request.
     *
     * @return array
     */
    protected function doCurl()
    {
        $response = curl_exec($this->curl);
        if (curl_errno($this->curl)) {
            throw new \Exception(curl_error($this->curl), 1);
        }
        $curlInfo = curl_getinfo($this->curl);
        $results = array(
                    'curl_info' => $curlInfo,
                    'response' => $response,
                   );
        return $results;
    }
}



这个差远了

连header都取不出

--- 共有 1 条评论 ---
螃蟹大叔php本来就差,反正我也是发一个别人实现,至于嘛,我只能呵呵 2年前 回复
无需curl,PHP核心自带的file_get_contents用stream_context_create设置http上下文后也可以POST数据,也支持HTTPS(跟curl底层都是依赖OpenSSL).
<?php
$data = array('Client' => 'jQuery', 'Server' => 'PHP');
$data = http_build_query($data); //生成一个经过URL编码的字符串Client=jQuery&Server=PHP
$options = array(
	'http' => array(
		'method' => 'POST',
		'header' => "Content-type: application/x-www-form-urlencoded\r\nCookie: foo=bar\r\n",
		'content' => $data,
		'timeout' => 1 //超时时间,单位:秒
	)
);
$context = stream_context_create($options);
echo file_get_contents('http://127.0.0.1:8182', false, $context);
// http://127.0.0.1:8182/index.php 脚本内容为 var_export($_POST);
// 返回 array ( 'Client' => 'jQuery', 'Server' => 'PHP', )

PHP用curl_multi并行获取多个HTTP接口数据

串行:
<?php
$ch1 = curl_init();
$ch2 = curl_init();
curl_setopt($ch1, CURLOPT_URL, 'http://127.0.0.1:8080/');
curl_setopt($ch1, CURLOPT_HEADER, 0);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch2, CURLOPT_URL, 'http://127.0.0.2:8080/');
curl_setopt($ch2, CURLOPT_HEADER, 0);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1);
$starttime = microtime(true);
$json[] = curl_exec($ch1);
$json[] = curl_exec($ch2);
echo microtime(true) - $starttime."\n"; //耗时约3秒
curl_close($ch1);
curl_close($ch2);
var_export($json);
//输出:
3.002946138382
array (
  0 => '{"SERVER_NAME":"127.0.0.1"}',
  1 => '{"SERVER_NAME":"127.0.0.2"}',
)

并行:
<?php
$url[] = 'http://127.0.0.1:8080';
$url[] = 'http://127.0.0.2:8080';
$mh = curl_multi_init();
foreach($url as $k => $v) {
	$ch[$k] = curl_init($v);
	curl_setopt($ch[$k], CURLOPT_HEADER, 0); //不输出头
	curl_setopt($ch[$k], CURLOPT_RETURNTRANSFER, 1); //exec返回结果而不是输出,用于赋值
	curl_multi_add_handle($mh, $ch[$k]); //决定exec输出顺序
}
$running = null;
$starttime = microtime(true);
do { //执行批处理句柄
	curl_multi_exec($mh, $running); //CURLOPT_RETURNTRANSFER如果为0,这里会直接输出获取到的内容.如果为1,后面可以用curl_multi_getcontent获取内容.
	curl_multi_select($mh); //阻塞直到cURL批处理连接中有活动连接,不加这个会导致CPU负载超过90%.
} while ($running > 0);
echo microtime(true) - $starttime."\n"; //耗时约2秒
foreach($ch as $v) {
	$info[] = curl_getinfo($v);
	$json[] = curl_multi_getcontent($v);
	curl_multi_remove_handle($mh, $v);
}
curl_multi_close($mh);
var_export($json); 
var_export($info);
//输出:
2.0015449523926
array (
  0 => '{"SERVER_NAME":"127.0.0.1"}',
  1 => '{"SERVER_NAME":"127.0.0.2"}',
)




顶部