php curl 封装

class CurlClient
{
    private $_ch;
    private $response;

    private $options;
    private $curlErrno = 0;

    // default config
    private $_config = [
        CURLOPT_RETURNTRANSFER => true,     // true 将curl_exec()获取的信息以字符串返回,而不是直接输出。
        CURLOPT_FOLLOWLOCATION => true,     // true 时将会根据服务器返回 HTTP 头中的 "Location: " 重定向。(注意:这是递归的,"Location: " 发送几次就重定向几次,除非设置了 CURLOPT_MAXREDIRS,限制最大重定向次数。)。
        CURLOPT_HEADER         => false,    // 启用时会将头文件的信息作为数据流输出。 开启才能获取 响应的 header
        CURLOPT_VERBOSE        => false,     // true 会输出所有的信息,写入到STDERR,或在CURLOPT_STDERR中指定的文件。几乎不需要在生产中使用,调试时可用
        CURLOPT_AUTOREFERER    => true,     // true 时将根据 Location: 重定向时,自动设置 header 中的Referer:信息。
        CURLOPT_CONNECTTIMEOUT => 30,       // 在尝试连接时等待的秒数
        CURLOPT_TIMEOUT        => 30,       // 允许 cURL 函数执行的最长秒数。
        CURLOPT_SSL_VERIFYPEER => false,    // false 禁止 cURL 验证对等证书(peer's certificate)。要验证的交换证书可以在 CURLOPT_CAINFO 选项中设置,或在 CURLOPT_CAPATH中设置证书目录。
        CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'
    ];

    /**
     * @param array $options
     * @throws Exception
     */
    public function __construct($options = []) {
        $this->options = is_array($options) ? ($options + $this->_config) : $this->_config;
        try {
            $this->_ch = curl_init();
            $this->setOptions($this->options);
        } catch (Exception $e) {
            throw new Exception('Curl not installed');
        }
    }

    public function __destruct() {
        curl_close($this->_ch);
    }


    /**
     * @param $url
     * @return bool|string
     * @throws Exception
     */
    private function exec($url)
    {
        $this->setOption(CURLOPT_URL, $url);
        $this->response = curl_exec($this->_ch);
        $this->curlErrno = curl_errno($this->_ch);
        if (!$this->curlErrno) {
            if (isset($this->options[CURLOPT_HEADER]))
                if ($this->options[CURLOPT_HEADER]) {
                    $header_size = curl_getinfo($this->_ch, CURLINFO_HEADER_SIZE);
                    return substr($this->response, $header_size);
                }
            return $this->response;
        } else {
            throw new Exception(curl_error($this->_ch));
        }
    }

    /**
     * 返回curl错误状态 错误码7为连接不上,28为连接上了但请求返回结果超时
     * @return int
     */
    public function getCurlErrno() {
        return $this->curlErrno;
    }

    public function get($url, $params = [])
    {
        $this->setOption(CURLOPT_HTTPGET, true);

        return $this->exec($this->buildUrl($url, $params));
    }

    /**
     *
     *
     * 支持多维数组 和 文件上传
     *
     */
    public function httpPostRequest($url,$data = []){
        $this->setOption(CURLOPT_POST, true);
        $this->setOption(CURLOPT_POSTFIELDS, http_build_query($data));

        return $this->exec($url);
    }

    /**
     * Curl 原生post请求发送方式
     *
     * 用于需要post无key参数、post文件等
     */
    public function post($url, $data = [])
    {
        $this->setOption(CURLOPT_POST, true);
        $this->setOption(CURLOPT_POSTFIELDS, $data);

        return $this->exec($url);
    }

    /**
     * put 请求
     * @param $url
     * @param $data
     * @param array $params
     * @return bool|string
     * @throws Exception
     *
     */
    public function put($url, $data, $params = [])
    {
        // write to memory/temp
        $f = fopen('php://temp', 'rw+');
        fwrite($f, $data);
        rewind($f);

        $this->setOption(CURLOPT_PUT, true);
        $this->setOption(CURLOPT_INFILE, $f);
        $this->setOption(CURLOPT_INFILESIZE, strlen($data));

        return $this->exec($this->buildUrl($url, $params));
    }

    /**
     * delete 请求
     * @param $url
     * @param array $params
     * @return bool|string
     * @throws Exception
     */
    public function delete($url, $params = [])
    {
        $this->setOption(CURLOPT_RETURNTRANSFER, true);
        $this->setOption(CURLOPT_CUSTOMREQUEST, 'DELETE');

        return $this->exec($this->buildUrl($url, $params));
    }

    /**
     * 创建请求连接
     * @param $url
     * @param array $data
     * @return string
     */
    public function buildUrl($url, $data = [])
    {
        $parsed = parse_url($url);
        isset($parsed['query']) ? parse_str($parsed['query'], $parsed['query']) : $parsed['query'] = [];
        $params = isset($parsed['query']) ? array_merge($parsed['query'], $data) : $data;
        $parsed['query'] = ($params) ? '?' . http_build_query($params) : '';
        if (!isset($parsed['path'])) {
            $parsed['path']='/';
        }

        $parsed['port'] = isset($parsed['port'])?':'.$parsed['port']:'';

        return $parsed['scheme'].'://'.$parsed['host'].$parsed['port'].$parsed['path'].$parsed['query'];
    }

    /**
     * 设置 curl opt
     * @param array $options
     * @return $this
     */
    public function setOptions($options = [])
    {
        curl_setopt_array($this->_ch, $options);

        return $this;
    }

    /**
     * 设置 curl opt
     * @param $option
     * @param $value
     * @return $this
     */
    public function setOption($option, $value)
    {
        curl_setopt($this->_ch, $option, $value);

        return $this;
    }

    /**
     * 设置请求 header
     * @param array $header
     * @return $this
     */
    public function setHeaders($header = [])
    {
        if ($this->isAssoc($header)) {
            $out = [];
            foreach ($header as $k => $v) {
                $out[] = $k .': '.$v;
            }
            $header = $out;
        }

        $this->setOption(CURLOPT_HTTPHEADER, $header);

        return $this;
    }

    private function isAssoc($arr)
    {
        return array_keys($arr) !== range(0, count($arr) - 1);
    }

    /**
     * 返回当前会话最后一次错误的字符串
     * @return string
     */
    public function getError()
    {
        return curl_error($this->_ch);
    }

    /**
     * 获取一个cURL连接资源句柄的信息
     * @return mixed
     */
    public function getInfo()
    {
        return curl_getinfo($this->_ch);
    }

    /**
     * 获取请求状态
     * @return mixed
     */
    public function getStatus()
    {
        return curl_getinfo($this->_ch, CURLINFO_HTTP_CODE);
    }

    /**
     * 重置一个 curl 会话句柄的所有的选项
     * @param array $options
     */
    public function reset($options = []) {
        curl_reset($this->_ch);
        $this->options = is_array($options) ? ($options + $this->_config) : $this->_config;
        $this->setOptions($this->options);
    }

    /**
     * 获取响应 headers  curl 设置  CURLOPT_HEADER  true 才能获取响应的 headers
     *
     * @return array
     */
    public function getResponseHeaders()
    {
        $headers = [];

        $header_text = substr($this->response, 0, strpos($this->response, "\r\n\r\n"));

        foreach (explode("\r\n", $header_text) as $i => $line) {
            if ($i === 0) {
                $headers['http_code'] = $line;
            } else {
                list ($key, $value) = explode(': ', $line);

                $headers[$key] = $value;
            }
        }

        return $headers;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值