- 类名称:curl
- 1.支持单个get,post请求
- 2.支持多个目标未登录get请求
- 3.支持单个目标并行多个get,post请求
- 4.支持ajax请求
- 5.支持自定义header请求
- 6.支持自定义编码数据请求(该情况比较特殊)
- 7.支持代理登陆
- 8.支持自定义来路
- 9.支持自定义超时
- 10.支持文件上传
<?php
/**
* 类名称:curl
* 1.支持单个get,post请求
* 2.支持多个目标未登录get请求
* 3.支持单个目标并行多个get,post请求
* 4.支持ajax请求
* 5.支持自定义header请求
* 6.支持自定义编码数据请求(该情况比较特殊)
* 7.支持代理登陆
* 8.支持自定义来路
* 9.支持自定义超时
* 10.支持文件上传
*/
/**
* demo1 get 请求
* curl()->get("http://www.baidu.com")->body();
*/
/**
* demo2 post请求
* curl()->post("http://www.xxx.com/say.php",array(
* 'data' => array(
* 'title' => 'test title',
* 'content' => 'test content',
* ),
* ))->body();
*/
/**
* demo3 post请求 ajax请求 并设置cookie
* curl()->post("http://www.xxx.com/save.php",array(
* 'data' => array(
* 'username' => 'test',
* 'password' => 'test'
* ),
* 'cookie_file' => '/tmp/cookie.txt',
* 'ajax' => 1,
* ))->body();
*/
/***
* demo4 批处理get请求
* curl()->get(array(
* 'http://www.xxx.com/test1.php?aaa=111',
* 'http://www.xxx.com/test2.php?aaa=222',
* 'http://www.xxx.com/test3.php?aaa=333',
* ))->body();
*/
/***
* demo5 批处理post请求 post请求,目前只支持单个网站的批处理post请求
* curl()->post(array(
* 'http://www.xxx.com/test1.php',
* 'http://www.xxx.com/test2.php',
* 'http://www.xxx.com/test3.php',
* ),array(
* 'data' => array(
* array(
* 'uid' => 'aabbccdd',
* ),
* array(
* 'uid' => 'eeeeeeee',
* ),
* array(
* 'uid' => 'ffffffff',
* ),
* ),
* 'cookie_file' => '/tmp/cookie.txt'
* ))->body();
*/
/**
* demo6 文件上传
* curl()->post('填写url地址',array(
* 'files' => array(
* 'pic' => '/tmp/a.gif' ,
* ),
* ))->body();
*/
/**
* 其他方法未一一列举,可查看源码进行测试
*/
class Curl {
//单例对象
private static $ins = null;
//请求结果
private $body = null;
//cookie文件
private $cookieFile = null;
//支持的请求方法
private $method = array('get','post');
//禁用初始化方法
final private function __construct()
{
}
/**
* 单例化对象
*/
public static function exec()
{
if (self::$ins) {
return self::$ins;
}
return self::$ins = new self();
}
/**
* 禁止克隆对象
*/
public function __clone()
{
throw new curlException('错误:不能克隆对象');
}
/**
* 调用不存在的方法被调用
*/
public function __call($method, $args)
{
if(!in_array($method,$this->method)) {
throw new curlException("错误:不支持{
$method}方法,支持的方法有"
. join(',',$this->method));
}
return $this->request($method, $args);
}
/**
* 返回执行结果
*/
public function body()
{
return $this->body;
}
/**
* 执行请求
* @param type $method
* @param type $args
* @return 返回对象本身
*/
private function request($method, $args)
{
if (isset($args[1]['multi'])) {
$this->body = $this->multiExecCurl($method, $args);
} else {
$this->body = $this->execCurl($method, $args);
}
return $this;
}
/**
* curl 批处理请求
* @param type $method
* @param type $args
* @return type
*/
public function multiExecCurl($method, $args)
{
$urls = isset($args[0]) ? $args[0] : "";
$data = isset($args[1]['data']) ? $args[1]['data'] : "";
$ajax = isset($args[1]['ajax']) ? $args[1]['ajax'] : "";
$timeout = isset($args[1]['timeout']) ? $args[1]['timeout'] : 30;
$referer = isset($args[1]['referer']) ? $args[1]['referer'] : "";
$proxy = isset($args[1]['proxy']) ? $args[1]['proxy'] : "";
$headers = isset($args[1]['headers']) ? $args[1]['headers'] : "";
if (!is_array($urls) || (is_array($urls) && empty($urls))) {
throw new curlException("错误信息:批处理url必须是数组并且不能为空");
}
//创建批处理cURL句柄
$queue = curl_multi_init();
//取得cookie文件路径
if(!$this->cookieFile) {
$this->cookieFile = isset($args[1]['cookie_file'])
? $args[1]['cookie_file'] : "";
}
//如果未获取到浏览器环境信息,就手动指定一个
$userAgent = isset($_SERVER['HTTP_USER_AGENT'])
? $_SERVER['HTTP_USER_AGENT']
: 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:23.0) '
.'Gecko/20100101 Firefox/23.0';
//设置CURL OPT选项
$options = array(
CURLOPT_TIMEOUT => $timeout, //超时
CURLOPT_RETURNTRANSFER => 1, //输出数据流
CURLOPT_HEADER => 0, //禁止头文件数据流输出
CURLOPT_FOLLOWLOCATION => 1, //自动跳转追踪
CURLOPT_AUTOREFERER => 1, //自动设置来路信息
CURLOPT_SSL_VERIFYPEER => 0, //认证证书检查
CURLOPT_SSL_VERIFYHOST => 0, //检查SSL加密算法
CURLOPT_HEADER => 0, //禁止头文件输出
CURLOPT_NOSIGNAL => 1, //忽略php所有的传递信号
CURLOPT_USERAGENT => $userAgent,//浏览器环境字符串
CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4, //ipv4寻址方式
CURLOPT_ENCODING => 'gzip', //解析使用gzip压缩的网页
);
//检测是否存在代理请求
if (is_array($proxy) && !empty($proxy)) {
$options[CURLOPT_PROXY] = $proxy['host'];
$options[CURLOPT_PROXYPORT] = $proxy['port'];
$options[CURLOPT_PROXYUSERPWD] =
$proxy['user'] . ':' . $proxy['pass'];
}
//header选项
$headerOptions = array();
//模拟AJAX请求
if ($ajax) {
$headerOptions['X-Requested-With'] = 'XMLHttpRequest';
}
if ($this->cookieFile) {
$options[CURLOPT_COOKIEFILE] = $this->cookieFile;
$options[CURLOPT_COOKIEJAR] = $this->cookieFile;
}
if ($referer) {
$options[CURLOPT_REFERER] = $referer;
}
if (!empty($headerOptions)) {
$options[CURLOPT_HTTPHEADER] = $headerOptions;
}
//循环的进行初始化一个cURL会话
foreach ($urls as $k => $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
if ($method == 'post') {
//发送一个常规的POST请求,
//类型为:application/x-www-form-urlencoded,就像表单提交的一样
$options[CURLOPT_POST] = 1;
//使用HTTP协议中的"POST"操作来发送数据,支持键值对数组定义
//注意:即使不使用http_build_query也能自动编码
$options[CURLOPT_POSTFIELDS] = $data[$k];
}
curl_setopt_array($ch,$options);
curl_multi_add_handle($queue, $ch);
}
//初始化变量
$responses = array();
$active = null;
//循环运行当前 cURL 句柄的子连接
do {
while (($code = curl_multi_exec($queue,
$active)) == CURLM_CALL_MULTI_PERFORM);
if ($code != CURLM_OK) {
break;
}
//循环获取当前解析的cURL的相关传输信息
while ($done = curl_multi_info_read($queue)) {
//获取最后一次传输的相关信息
$info = curl_getinfo($done['handle']);
//从最后一次传输的相关信息中找 http_code 等于200
if ($info['http_code'] == 200) {
//如果设置了CURLOPT_RETURNTRANSFER,获取的输出的文本流
$responses[] = curl_multi_getcontent($done['handle']);
}
//移除curl批处理句柄资源中的某个句柄资源
curl_multi_remove_handle($queue, $done['handle']);
//关闭某个批处理句柄会话
curl_close($done['handle']);
}
if ($active > 0) {
//等待所有cURL批处理中的活动连接
curl_multi_select($queue, 0.5);
}
} while ($active);
//关闭一组cURL句柄
curl_multi_close($queue);
//返回结果
return $responses;
}
/**
* curl 单句柄请求
* @param type $method
* @param type $args
* @return type
*/
private function execCurl($method, $args)
{
//解析参数
$url = isset($args[0]) ? $args[0] : "";
$multi = isset($args[1]['multi']) ? $args[1]['multi'] : "";
$data = isset($args[1]['data']) ? $args[1]['data'] : "";
$ajax = isset($args[1]['ajax']) ? $args[1]['ajax'] : "";
$timeout = isset($args[1]['timeout']) ? $args[1]['timeout'] : 30;
$files = isset($args[1]['files']) ? $args[1]['files'] : "";
$referer = isset($args[1]['referer']) ? $args[1]['referer'] : "";
$proxy = isset($args[1]['proxy']) ? $args[1]['proxy'] : "";
$headers = isset($args[1]['headers']) ? $args[1]['headers'] : "";
//如果环境变量的浏览器信息不存在,就是用手动设置的浏览器信息
$userAgent = isset($_SERVER['HTTP_USER_AGENT'])?
$_SERVER['HTTP_USER_AGENT']:
'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:23.0)
Gecko/20100101 Firefox/23.0';
//检测url必须参数 不能为空
if (!$url) {
throw new curlException("错误:curl请求地址不能为空");
}
//设置curl选项
$options = array(
CURLOPT_URL => $url, //目标url
CURLOPT_TIMEOUT => $timeout, //超时
CURLOPT_RETURNTRANSFER => 1, //输出数据流
CURLOPT_FOLLOWLOCATION => 1, //自动跳转追踪
CURLOPT_AUTOREFERER => 1, //自动设置来路信息
CURLOPT_SSL_VERIFYPEER => 0, //认证证书检查
CURLOPT_SSL_VERIFYHOST => 0, //检查SSL加密算法
CURLOPT_HEADER => 0, //禁止头文件输出
CURLOPT_NOSIGNAL => 1, //忽略所有传递的信号
CURLOPT_USERAGENT => $userAgent,//浏览器环境字符串
CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4, //ipv4寻址方式
CURLOPT_ENCODING => 'gzip', //解析使用gzip压缩的网页
);
//获取cookie文件地址路径
if(!$this->cookieFile) {
$this->cookieFile = isset($args[1]['cookie_file'])
? $args[1]['cookie_file'] : "";
}
//设置代理 必须是数组并且非空
if (is_array($proxy) && !empty($proxy)) {
$options[CURLOPT_PROXY] = $proxy['host'];
$options[CURLOPT_PROXYPORT] = $proxy['port'];
$options[CURLOPT_PROXYUSERPWD] =
$proxy['user'] . ':' . $proxy['pass'];
}
//检测是否未启用自定义urlencode编码
if (!isset($args[1]['build'])) {
if ($data && $method == "post" && is_array($data)) {
$data = http_build_query($data, '', '&');
}
}
//检测是否含有上传文件
if ($files && $method == "post" && is_array($files)) {
foreach ($files as $k => $v) {
$files[$k] = '@' . $v;
}
parse_str($data, $data);
$data = $data + $files;
}
//检测判断是否是post请求
if ($method == 'post') {
//发送一个常规的POST请求
$options[CURLOPT_POST] = 1;
//使用HTTP协议中的"POST"操作来发送数据,支持键值对数组定义
$options[CURLOPT_POSTFIELDS] = $data;
}
//初始化header数组
$headerOptions = array();
//检测是否是ajax提交
if ($ajax) {
$headerOptions['X-Requested-With'] = 'XMLHttpRequest';
}
//设置cookie
if ($this->cookieFile) {
$options[CURLOPT_COOKIEFILE] = $this->cookieFile;
$options[CURLOPT_COOKIEJAR] = $this->cookieFile;
}
//设置来路
if ($referer) {
$options[CURLOPT_REFERER] = $referer;
}
//合并header
if (!empty($headers) && is_array($headers)) {
foreach ($headers as $k => $v) {
$headerOptions[$k] = $v;
}
}
//转换header选项为浏览器header格式
if (!empty($headerOptions) && is_array($headerOptions)) {
$array = array();
foreach($headerOptions as $k => $v) {
$array[] = $k . ": " . $v;
}
$options[CURLOPT_HTTPHEADER] = $array;
}
//创建curl句柄
$ch = curl_init();
//设置curl选项
curl_setopt_array($ch, $options);
//获取返回内容
$content = curl_exec($ch);
//关闭curl句柄
curl_close($ch);
//返回内容
return $content;
}
/**
* 对一个对象进行字符串echo输出
* 自动调用__toString方法
* @return type
*/
public function __toString()
{
return $this->body();
}
}
class curlException extends Exception {
}
//curl方法不存在就设置一个curl方法
if (!function_exists('curl')) {
function curl() {
return curl::exec();
}
}
转载:https://blog.csdn.net/wangzhae/article/details/109560377
查看评论