前言

我对于cURL的使用比较频繁,因为要写API接口嘛时不时就要用到,之前查到一个不是特别好用,自己改良添加了一些参数。

代码

/**
 * @function Curl的封装,方便调用
 * @author 木小果
 * @link https://blog.muxiaoguo.cn
 * @param String $url 需要访问的链接
 * @param Param $paras 各种参数
 * @message phpCurl封装的方法
 * @modificatioTime 2021年08月23日
 * */
function runCurl($url, $paras = array())
{
    $ch = curl_init();//初始化一个cURL会话
    curl_setopt($ch, CURLOPT_URL, $url);//需要访问的网址
    /**
     * 如果是抓取HTTPS,把下面两项设置为false:
     * 禁用后CURL将终止从服务端进行验证.使用CURLOPT_CAINFO选项设置证书使用CURLOPT_CAPATH选项设置证书目录
     * 如果CURLOPT_SSL_VERIFYPEER(默认值为2)被启用,CURLOPT_SSL_VERIFYHOST需要被设置成TRUE否则设置为FALSE.
     * */
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);//跳过SSL证书验证
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);//跳过SSL证书验证
    //curl_setopt ($ch, CURLOPT_COOKIEJAR, __DIR__."/cookies.txt");//连接结束后是否保存cookie信息的文件
    /**
     * 一个用来设置HTTP头字段的数组.
     * 使用如下的形式的数组进行设置: array('Content-type: text/plain', 'Content-length: 100')
     * curl_setopt ($ch, CURLOPT_HTTPHEADER, array('CLIENT-IP:125.210.188.36', 'X-FORWARDED-FOR:125.210.188.36'));
     * */
    if (@$paras['Header']) {//请求标头
        $Header = $paras['Header'];
    } else {//若Header参数为空的默认请求标头
        $Header[] = "Accept:*/*";
        $Header[] = "Accept-Encoding:gzip,deflate,sdch";
        $Header[] = "Accept-Language:zh-CN,zh;q=0.8";
        $Header[] = "Connection:close";
        /**
         * 下面这个伪造请求IP的方法方法大多数能糊弄过去,但也有抓到了真实IP的.
         * 就使用代理,麻烦在于你有一个有效的代理ip和端口号,有的还需要用户名密码
         * */
        $randIP = randIp();//取随机IP
        $Header[] = 'X-Forwarded-For: '.$randIP;//伪造请求IP
        $Header[] = 'Remote_Addr: '.$randIP;//伪造请求IP
        $Header[] = 'Client-Ip: '.$randIP;//伪造请求IP
    }
    curl_setopt($ch, CURLOPT_HTTPHEADER, $Header);//一个用来设置HTTP头字段的数组
    if (@$paras['diRedi']) {
        /**
         * 禁止重定向(不会跟踪重定向页面,301或302跳转时禁止跳转)
         * 启用时会将服务器服务器返回的"Location: "放在header中递归的返回给服务器,
         * 使用 CURLOPT_MAXREDIRS 可以限定递归返回的数量
         * */
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    }
    if (@$paras['proxyIP']) {
        $temp = $paras['proxyIP'];//赋值到临时变量
        $temp = explode(ste_replace(':',':',$temp),$temp);//将中文冒号替换为英文冒号并打散
        //代理IP_方法1(这个好像不太行)
        //curl_setopt ($ch, CURLOPT_PROXY, $paras['proxy']['ip'].':'.$paras['proxy']['port']);// http://104.16.244.204:443/ 或 IP+端口
        //代理IP_方法2
        curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL,true);//启用 http 代理隧道(TRUE 会通过指定的 HTTP 代理来传输.)
  
        //HTTP代理连接的验证方式.使用在 CURLOPT_HTTPAUTH 中的位域标志来设置相应选项.对于代理验证只有 CURLAUTH_BASIC 和 CURLAUTH_NTLM 当前被支持.
        curl_setopt($ch, CURLOPT_PROXYAUTH,CURLAUTH_BASIC);
  
        //HTTP代理通道. 也就是常说的IP地址
        curl_setopt($ch, CURLOPT_PROXY,$paras['proxyIP']['ip']);//代理服务器地址
  
        //代理服务器的端口.端口也可以在CURLOPT_PROXY中进行设置.
        curl_setopt($ch, CURLOPT_PROXYPORT,$paras['proxyIP']['port']);//代理服务器端口

        //此参数不是 CURLPROXY_HTTP (默认值) 就是 CURLPROXY_SOCKS5.
        curl_setopt($ch, CURLOPT_PROXYTYPE,CURLPROXY_HTTP);//使用http代理模式
    }
    if (@$paras['conTimedout']) {//连接超时(在发起连接前等待的时间,若参数为0,则无限等待)
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $paras['conTimedout']);
    } else {
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);//默认15
    }
    if (@$paras['readTimeout']) {//读取超时(设置cURL允许执行的最长秒数)
        curl_setopt($ch, CURLOPT_TIMEOUT, $paras['readTimeout']);
    } else {
        curl_setopt($ch, CURLOPT_TIMEOUT, 15);//默认15
    }
    if (@$paras['post']) {//POST请求
        curl_setopt($ch, CURLOPT_POST, true);//启用时会发送一个常规的POST请求
        if (@isset($paras['post']['toText'])) {//是否需要将数组转换为文本
            unset($paras['post']['toText']);//数组中清除这个键值,此键仅用于判断
            $paras['post'] = http_build_query($paras['post']);//将数组内容转为GET参数形式(parse_url()函数可以反向将GET参数转换为数组)
            curl_setopt($ch, CURLOPT_POSTFIELDS, $paras['post']);//设置POST参数
        }else{
            curl_setopt($ch, CURLOPT_POSTFIELDS, $paras['post']);//默认提交方式
        }
        /**
         * 全部数据使用HTTP协议中的"POST"操作来发送.
         * 要发送文件,在文件名前面加上@前缀并使用完整路径.
         * 这个参数可以通过urlencoded后的字符串类似'para1=val1&para2=val2&...'
         * 或使用一个以字段名为键值,字段数据为值的数组.
         * 如果value是一个数组,Content-Type头将会被设置成multipart/form-data.
         */
    }
    if (@$paras['backHeader']) {
        curl_setopt($ch, CURLOPT_HEADER, true);//查看返回的Header信息(启用时会将头文件的信息作为数据流输出)
    }
    if (@$paras['cookie']) {//设置Cookie
        //设定HTTP请求中"Cookie: "多cookie用分号隔开,分号后带空格(如:"fruit=apple; colour=red").
        curl_setopt($ch, CURLOPT_COOKIE, $paras['cookie']);
    }
    if (@$paras['refer']) {//在HTTP请求头中"Referer: "的内容.(模拟/伪造来路)
        curl_setopt($ch, CURLOPT_REFERER, $paras['refer']);
    }
    if (@$paras['ua']) {//在HTTP请求中包含一个"User-Agent: "头的字符串.
        curl_setopt($ch, CURLOPT_USERAGENT, $paras['ua']);
    } else {
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36");//默认 Google User-Agent
    }
    if (@$paras['noBody']) {//启用时将不对HTML中的BODY部分进行输出
        curl_setopt($ch, CURLOPT_NOBODY, true);
    }
    //请求头中"Accept-Encoding: "的值.支持编码有'identity','deflate'和'gzip',若为空,请求头会发送所有支持的编码类型.
    if (@$paras['noBody']) {
        curl_setopt($ch, CURLOPT_ENCODING, $paras['noBody']);//自定义
    }else{
        curl_setopt($ch, CURLOPT_ENCODING, 'gzip,identity,deflate');//默认
    }
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);//获取的信息以文件流的形式返回,而不是直接输出
    /*判断是否需要请求的全部信息*/
    if (@$paras['GetCookie']) {
        curl_setopt($ch, CURLOPT_HEADER, true);//启用时会将头文件的信息作为数据流输出
        $result = curl_exec($ch);//执行一个cURL会话
        preg_match_all("/Set-Cookie: (.*?);/m", $result, $matches);
        $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);//获得响应头大小,有时可能需要PHP>=7.4/7.5
        $header = substr($result, 0, $headerSize); //状态码
        $body = substr($result, $headerSize);
        /**
         * 判断是否需要将网页源码转义
         * htmlspecialchars()函数,转义特别的字符为HTML实体
         * html_entity_decode()函数,把 HTML实体字符串 转换为字符
         * htmlentities()函数,这个是全部转换HTML实体,和 htmlspecialchars()区别在于,这个函数是转义全部的字符,而 htmlspecialchars()仅仅转义上面限定的5个特殊字符
         * htmlspecialchars_decode()函数 ,将实体转成HTML代码,函数1的反函数.有时候展示不出应有的效果,而是显示出h5代码.多半是需要使用这个函数的
         * */
        if (@isset($paras['GetCookie']['enentity'])) {
            //把预定义的字符转换为 HTML实体
            $body = htmlspecialchars($body);
        }
        if (@isset($paras['GetCookie']['deentity'])) {
            //把 HTML实体字符串 转换为字符
            $body = html_entity_decode($body);
        }
        $ret = [
            "Cookie" => $matches, "body" => $body, "header" => $header, 'code' => curl_getinfo($ch, CURLINFO_HTTP_CODE)
        ];
        curl_close($ch);//关闭cURL会话
        return $ret;//返回结果
    }
    $ret = curl_exec($ch);//执行一个cURL会话
    if (@$paras['loadurl']) {//获取301跳转地址
        $Headers = curl_getinfo($ch);
        if (isset($Headers['redirect_url'])) {
            $ret = $Headers['redirect_url'];
        } else {
            $ret = false;
        }
    }
    curl_close($ch);
    if (@$paras['toUtf8']) {//编码转换
        $ret = mb_convert_encoding($ret, 'utf-8','GB2312');//把 GB2312 转到 UTF-8
    }
    if (@$paras['toHtml']) {//转换为HTML源码输出(打印后就不是打开网页了而是显示源码)
        $ret = htmlspecialchars($ret);
        /*这里必须替换字符串才能拿到正常无乱码的网页源代码*/
        $ret = str_replace('"','"',$ret);//替换字符
        $ret = str_replace('&lt;','<',$ret);//替换字符
        $ret = str_replace('&gt;','>',$ret);//替换字符
        $ret = str_replace('</a>','',$ret);//替换字符
        $ret = str_replace('</span>','',$ret);//替换字符
    }
    return $ret;
}

使用方法

GET访问

echo runCurl('https://api.muxiaoguo.cn/api/chePhone?phoneNum=13786310544');

POST访问

echo runCurl('https://api.muxiaoguo.cn/api/chePhone',[
    'post' => [
        'phoneNum' => '13786310544'
    ]
]);

echo runCurl('https://api.muxiaoguo.cn/api/chePhone?',[
    'post' => 'phoneNum=13786310544'
]);

echo runCurl('https://api.muxiaoguo.cn/api/chePhone?',[
    'post' => [
        //有时使用数组形式提交服务器无法解析就需要用 toText 参数,参数太多不想一个个改,将数组形式的数据改为get文本格式,toText键与键值会自动删除
        'toText' => true,
        'phoneNum' => '13786310544'
    ]
]);

携带Cookie访问

也可以在设置请求标头时一起提交

echo runCurl('https://api.muxiaoguo.cn/api/chePhone?phoneNum=13786310544',[
    'cookie' => 'cookie内容'
]);

模拟访问来源Refer

也可以在设置请求标头时一起提交

echo runCurl('https://api.muxiaoguo.cn/api/chePhone?phoneNum=13786310544',[
    'refer' => 'https://api.muxiaoguo.cn/'
]);

模拟UseaAgent

也可以在设置请求标头时一起提交

echo runCurl('https://api.muxiaoguo.cn/api/chePhone?phoneNum=13786310544',[
    'ua' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
]);

文件上传

echo runCurl("https://api.muxiaoguo.cn/api/chePhone?phoneNum=13786310544",[
    'post'=>[
        'file' => new CURLFile(realpath("Curl.jpg"))
    ]
]);

echo runCurl("https://api.muxiaoguo.cn/api/chePhone?phoneNum=13786310544",[
    'post' => new CURLFile(realpath("Curl.jpg"))
]);

获取301跳转地址

echo runCurl("http://suo.nz/4NzTZ4",[
    'loadurl' => true
]);

查看返回Header信息

echo runCurl("https://api.muxiaoguo.cn/api/chePhone?phoneNum=13786310544",[
    'backHeader' => true
]);

设置请求头信息

echo runCurl("https://api.muxiaoguo.cn/api/chePhone?phoneNum=13786310544",[
    'Header'=>[
        'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
        'accept-encoding: gzip, deflate, br',
        'accept-language: zh-CN,zh;q=0.9',
        'cache-control: max-age=0'
    ]
]);

echo runCurl("https://api.muxiaoguo.cn/api/chePhone?phoneNum=13786310544",[
    'Header'=>[
        'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
        accept-encoding: gzip, deflate, br
        accept-language: zh-CN,zh;q=0.9
        cache-control: max-age=0'
    ]
]);

获取请求的全部信息

var_dump(
    runCurl('https://api.muxiaoguo.cn/api/chePhone',[
        'post' => 'phoneNum=13786310544',
        'GetCookie'=> true
    ])
);

var_dump(
runCurl('https://api.muxiaoguo.cn/api/chePhone',[
'post' => 'phoneNum=13786310544',
'GetCookie'=> [
'enentity' => true//将body中的预定义的字符转换为 HTML 实体
]
])
);

var_dump(
    runCurl('https://api.muxiaoguo.cn/api/chePhone',[
        'post' => 'phoneNum=13786310544',
        'GetCookie'=> [
            'deentity' => true//将body中的 HTML实体字符串 转换为字符
        ]
    ])
);

最后

还支持更多功能比如HTTP代理、Utf8编码转换、Html输出等,自己探索吧!~

最后修改:2022 年 11 月 17 日
如果觉得我的文章对你有用,请随意赞赏~