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;
}
}
php curl 封装
最新推荐文章于 2024-05-23 16:09:21 发布