<?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;
}
}