php curl请求

2020-08-19
<?php

class Curl
{
    /**
     * @description: 
     * @var object CURL对象
     */
    private $_curl;

    /**
     * @description: 
     * @var string 请求结果
     */
    private $_body;

    /**
     * @description: 
     * @var string 请求参数
     */
    private $_param;

    /**
     * @description: 
     * @var string 响应头
     */
    private $_header;

    /**
     * @description: 
     * @var string 请求方法
     */
    private $_method;

    /**
     * @description: 
     * @var array CURL参数
     */
    private $_curl_opt;

    /**
     * @description: 
     * @var string User-Agent
     */
    private $_user_agent = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36';

    /**
     * @description: 
     * @param string $url 请求url
     * @param int $time 超时时间
     * @param string $type 请求类型
     * @param string|array $param 请求参数
     * @param array $opts curl参数
     * @return
     */
    public function __construct(string $url = '', int $time = 60, string $type = 'get', $param = [], array $opts = [])
    {
        $this->_curl = curl_init();
        if ($url) {
            $this->ini_curl($url, $time, $type, $param, $opts);
        }
    }

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

    /**
     * @description: 初始化请求体,默认禁止了https的CA证书校验
     * @param string $url 请求url
     * @param int $time 超时时间
     * @param string $type 请求类型
     * @param string|array $param 请求参数
     * @param array $opts curl参数
     * @return void
     */
    public function ini_curl(string $url, int $time = 60, string $type = 'get', $param = [], array $opts = []):void
    {
        $this->_param = $param;
        $this->_method = strtoupper($type);
        $this->_curl_opt = [
            CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => 1, CURLOPT_TIMEOUT => $time, CURLOPT_HEADER => 1, CURLOPT_USERAGENT => $this->_user_agent,
            CURLINFO_HEADER_OUT => true, CURLOPT_SSL_VERIFYPEER => false
        ];
        if ($this->_method == 'POST') {
            $this->_curl_opt[CURLOPT_POST] = 1;
        }
        if (!empty($param)) {
            $this->_curl_opt[CURLOPT_POSTFIELDS] = $param;
        }
        curl_setopt_array($this->_curl, $this->_curl_opt);
        $this->set_opt($opts);
    }

    /**
     * @description: 设置CURL参数
     * @param array $opts
     * @return void
     */
    public function set_opt(array $opts = []):void
    {
        foreach ($opts as $key => $val) {
            curl_setopt($this->_curl, $key, $val);
        }
    }

    /**
     * @description: 禁用https SSL证书验证
     * @param {*}
     * @return {*}
     */
    public function disableSSL()
    {
        $this->set_opt([
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
        ]);
    }

    /**
     * @description: 设置cookie
     * @param string $cookie
     * @return void
     */
    public function set_cookie($cookie):void
    {
        $this->_curl_opt[CURLOPT_COOKIE] = $cookie;
    }

    /**
     * @description: 请求
     * @return string
     */
    public function curl_func():string
    {
        $result        = curl_exec($this->_curl);
        $headerSize    = curl_getinfo($this->_curl, CURLINFO_HEADER_SIZE);
        $this->_header = substr($result, 0, $headerSize);
        $this->_body   = substr($result, $headerSize);
        $this->_log();
        
        if (preg_match('/^\xEF\xBB\xBF/',$this->_body)) { //curl返回的数据中可能带有bom格式,需要转换
            $this->_body = substr($this->_body, 3);
        }

        $code = curl_getinfo($this->_curl, CURLINFO_HTTP_CODE);
        if (((string)$code)[0] == '2') {
            return $this->_body;
        } else {
            return false;
        }
    }
 
    /**
     * @description: 在参数中上传文件
     * @param array|string $file 文件全路径
     * @param string $name 参数名
     * @param array $param 请求的其他参数
     * @return array
     */
    public function set_data_file($files, string $name = 'file', array &$param = []):array
    {
        $return = [];
        if (is_array($files)) {
            foreach ($files as $key => $file) {
                $return[$name.'['.$key.']'] = curl_file_create(realpath($file), mime_content_type($file), basename($file));
            }
        } else {
            $return = [$name => curl_file_create(realpath($files), mime_content_type($files), basename($files))];
        }
        if (!empty($param)) $param = array_merge($param, $return);
        return $return;
    }

    /**
     * @description: 获取cookie
     * @return string
     */
    public function get_cookie():string
    {
        preg_match("/set\-cookie:([^\r\n]*)/i", $this->_header, $matches);
        return explode(';', $matches[1])[0];
    }

    /**
     * @description: 获取响应头
     * @return string
     */
    public function get_header():string
    {
        return $this->_header;
    }

    /**
     * @description: 设置日志目录
     * @param string $dir
     * @return void
     */
    public function set_log_dir(string $dir):void
    {
        $this->_log_dir = $dir;
    }

    /**
     * @description: 获取日志目录
     * @return string
     */
    public function get_log_dir():string
    {
        return $this->_log_dir;
    }

    /**
     * @description: 记录请求日志
     * @return void
     */
    private function _log():void
    {
        error_log($this->_get_log_content(), 3, $this->_generate_log_file());
    }

    /**
     * @description: 获取日志内容
     * @return string
     */
    private function _get_log_content():string
    {
        $curl_info = curl_getinfo($this->_curl);
        $log = is_array($this->_param) ? json_encode($this->_param, JSON_UNESCAPED_UNICODE) : $this->_param;
        return '[ '.date('Y-m-d H:i:s').' ] ' . $this->_method . ' ' . $curl_info['url'] . PHP_EOL .
                '[ REQUEST HEADER]' . $curl_info['request_header'] . PHP_EOL .
                '[ PARAM ] ' . $log . PHP_EOL . 
                '[ ERROR ] ' . curl_strerror(curl_errno($this->_curl)) . PHP_EOL . 
                '[ RESPONSE HEADER ] ' . PHP_EOL . 
                $this->_header . PHP_EOL .
                '[ RESPONSE BODY ] ' . PHP_EOL . 
                $this->_body . PHP_EOL .
                '[ 消耗时间 ] ' . $curl_info['total_time'] . 's' . PHP_EOL;
    }

    /**
     * @description: 获取日志文件路径
     * @return string
     */
    private function _generate_log_file():string
    {
		$this->_log_dir = './log/' .  date('Ym') . '/';
		
        if (!is_dir($this->_log_dir)) {
            mkdir($this->_log_dir, 0777, true);
        }
        $log_file = $this->_log_dir . date('d') . '.log';
        if (is_file($log_file) && filesize($log_file) > 2097152) {
            rename($log_file, $this->_log_dir . date('dHis') . '_' . uniqid() . '.log');
        }
        return $log_file;
    }
}

 

{/if}