实用的 CURL 类-访问pc端接口

  • 参考PHP手册--设置 cURL 传输选项

cURL 是一个利用 URL 语法规定来传输文件和数据的工具,支持很多协议,如 HTTP、FTP、TELNET 等。最爽的是,PHP 也支持 cURL 库。使用 PHP 的 cURL 库可以简单和有效地去抓网页。你只需要运行一个脚本,然后分析一下你所抓取的网页,然后就可以以程序的方式得到你想要的数据了。无论是你想从从一个链接上取部分数据,或是取一个XML文件并把其导入数据库,那怕就是简单的获取网页内容.

GET请求带参数的时候,一定要转换成字符串形式http_build_query($post_data),不可以使用数组

CURLOPT_FOLLOWLOCATION 用于重定向的请求,有重定向的页面直接curl 访问可能会访问不到,使用这个参数即可

CURLOPT_SSL_VERIFYHOST 设置为 1 是检查服务器SSL证书中是否存在一个公用名(common name)。译者注:公用名(Common Name)一般来讲就是填写你将要申请SSL证书的域名 (domain)或子域名(sub domain)。 设置成 2,会检查公用名是否存在,并且是否与提供的主机名匹配。 0 为不检查名称。 在生产环境中,这个值应该是 2(默认值)。

脚本最大的执行时间是30S 这个时间并不是说30S之内请求数据的等待时间,而是说总共请求的时间,请求30S之后,就不在请求。会类似于 die 的作用。如果想取消时间限制,可以使用 set_time_limit(0);

/**
 * @param $url 请求网址
 * @param bool $params 请求参数
 * @param int $ispost 请求方式
 * @param int $https https协议
 * @param int $cookie 是否传递 cookie
 * @param int $proxy 是否需要代理
 * @return bool|mixed
 */
function curl($url, $params = false, $ispost = 0, $https = 0, $cookie = 0, $proxy = 0)
{
    $httpInfo = array();
    set_time_limit(0); // 默认脚本是请求30S,添加这个参数会一直请求,没有时间限制
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36');
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); // 这个是连接的时间,也就是多久503 timeout
    curl_setopt($ch, CURLOPT_TIMEOUT, 300); // 这个是执行的时间 最好不要设置太短
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回原生的内容
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 如果请求的数据有重定向,则追踪到重定向地址
    if ($https) {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 对认证证书来源的检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在
    }
    if ($ispost) {
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        curl_setopt($ch, CURLOPT_URL, $url);
    } else {
        if ($params) {
            if (is_array($params)) {
                $params = http_build_query($params);
            }
            curl_setopt($ch, CURLOPT_URL, $url . '?' . $params);
        } else {
            curl_setopt($ch, CURLOPT_URL, $url);
        }
    }
    if ($cookie) {
        curl_setopt($ch, CURLOPT_COOKIE, $cookie); // 注意,这个cookie 是需要你先登陆再去浏览器获取的
    }
    if ($proxy) {
        $proxyport = '8080'; // 注意这里的端口号需要自己设置
        curl_setopt($ch, CURLOPT_PROXY, $proxy);
        curl_setopt($ch, CURLOPT_PROXYPORT, $proxyport);
    }

    $response = curl_exec($ch);
    if (curl_errno($ch)) {
        echo "Error Occured in Curl\n";
        echo "Error number: " . curl_errno($ch) . "\n";
        echo "Error message: " . curl_error($ch) . "\n";
        curl_close($ch);
        return false;
    } else {
        // $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); // 有出现报错的时候,可以打印
        // $httpInfo = array_merge($httpInfo, curl_getinfo($ch));
        curl_close($ch);
        return $response;
    }
}

使用方法

  // 发送请求
$result = self::curl('网址', '参数', true);
// 收到的数据需要转化一下
$json = json_decode($result);

  • 如果我们输出内容发现有乱码,我们尝试json_decode()发现是不可以转换的。这个时候一般是GBK格式,我们只需要把结果转换一下即可
$response = iconv('GBK//IGNORE', 'UTF-8', $response);
$res = json_decode($response);
var_dump($res);
图片.png

请求的时候带cookie;如果有多个参数,中间用分号;隔开

 curl_setopt($ch,CURLOPT_COOKIE, "g=".$token.';'.'PHPSESSID='.$_COOKIE['PHPSESSID'] );
实用的 CURL 类-访问pc端接口_第1张图片
cookie值获取

cookie文件的使用

$cookie_file = "/tmp/tmp/cookies.txt";
function store_cookies($cookie_file)
    {
        //连接关闭以后,存放cookie信息的文件名称 (cookies stored in $cookie_file)
        curl_setopt ($this->ch, CURLOPT_COOKIEJAR, $cookie_file);
        //包含cookie信息的文件名称,这个cookie文件可以是Netscape格式或者HTTP风格的header信息
        curl_setopt ($this->ch, CURLOPT_COOKIEFILE, $cookie_file);
    }


注意

如果本地文件curl请求本地文件,需要传递session的话,有可能会出现只能请求一次的情况,再请求会失败。解决这个问他的方式是在执行curl_exec($ch)之前,执行session_write_close()。这个我查询文档是关闭会话的意思。但是如果请求其他站点就不需要这个处理了

查阅资料,这么解释
这是php session锁死的一种情况
使用session过程中,在开启session后,同一浏览器,执行同一程序,不同页面会被锁。不同浏览器不会出现这种情况。
结合了PHP的Session机制,找到了阻塞的原因。
由于PHP的Session信息是写入文件的,1个客户端占有1个session文件。
因此,当 session_start被调用的时候,该文件是被锁住的,而且是以读写模式锁住的
(因为程序中可能要修改session的值),这样,第2次调用 session_start的时候就被阻塞了。

包含头信息,来源位置

$useragent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
function set_user_agent($useragent)
    {
        //在HTTP请求中包含一个”user-agent”头的字符串
        curl_setopt($this->ch, CURLOPT_USERAGENT, $useragent);
    }

//来源位置
$referrer_url = 'http://www.google.com'
    function set_referrer($referrer_url)
    {
        //设置header中"Referer: " 部分的值
        curl_setopt($this->ch, CURLOPT_REFERER, $referrer_url);
    }

//在启用CURLOPT_RETURNTRANSFER时候将获取数据返回
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER,true);

// 允许重新定向
        curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, true);
        // 如果有gzip则解压
        curl_setopt($this->ch,CURLOPT_ENCODING , 'gzip, deflate ,sdch');

//HTTP认证
    function set_credentials($username,$password)
    {
        curl_setopt($this->ch, CURLOPT_USERPWD, "$username:$password");
    }

使用代理url请求

$proxyport = "808";
curl_setopt($ch,CURLOPT_PROXY,$proxy);
curl_setopt($ch,CURLOPT_PROXYPORT,$proxyport);

设置POST请求

curl_setopt ( $ch, CURLOPT_POST, 1 );  //设置POST请求
curl_setopt ( $ch, CURLOPT_HTTPHEADER, array (
                'Content-type:application/x-www-form-urlencoded;charset=UTF-8' 
        ) );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $data );  //请求参数
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );  

使用json格式请求

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data))
);

HTML高亮显示

//高亮HTML $line_number 显示行号
    function highlightHtml($code,$line_number=false)
    {
        //$code=$this->results;
        $code = htmlspecialchars($code);
        //$code = str_replace(" "," ",$code); //替换空格替换为 
        //$code = nl2br($code); //将回车替换为
//htm标签 //$code = preg_replace_callback('/<([a-zA-Z0-9]+)(.*?)(\/?>)/',array('WebLoad','__pv'), $code); $code = preg_replace('/(<[a-zA-Z0-9]+)/', '$1', $code); $code = preg_replace('/(<\/[a-zA-Z0-9]+>)/', '$1', $code); $code = preg_replace('/(\/>)/', '${1}', $code); //$code = preg_replace('/(<\/?[a-zA-Z]+ .*?>)/','${1}', $code); $code = preg_replace('//','${0}',$code); //注释 $code = str_replace('', '-->', $code); //--------------以下是专为visualTpl模板文件而定制的高亮代码-------- //block : begin|end $code = preg_replace('/(<\/em><\/font>/i', '${0}', $code); //ssi : #include $code = preg_replace('//i','${0}',$code); //无格式变量 $code = preg_replace('/(\{\$[a-zA-Z0-9_\x7f-\xfe]+\})/','${1}', $code); //格式变量 $code = preg_replace('/(\{\$[a-zA-Z0-9_\x7f-\xfe]+;)([a-zA-Z]+)=\'([^\']+?)\'\}/','${1}${2}=\'${3}\'}', $code); //--------------定制代码结束-------------- //$code = preg_replace_callback('/>[^<]+?'.$code.'
'; }else{ $code = '
  1. ' . str_replace("\n",'
  2. ',$code) . '
'; return $code; } }

PHP 下载远程图片

class Spider {
    public function downloadImage($url, $path='images/')

    {

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);

        $file = curl_exec($ch);

        curl_close($ch);


        $this->saveAsImage($url, $file, $path);

    }


    private function saveAsImage($url, $file, $path)

    {

        $filename = pathinfo($url, PATHINFO_BASENAME);

        $resource = fopen($path . $filename, 'a');

        fwrite($resource, $file);

        fclose($resource);

    }
}

使用
$images = [

    'https://dn-laravist.qbox.me/2015-09-22_00-17-06j.png',

    'https://dn-laravist.qbox.me/2015-09-23_00-58-03j.png'

];
$spider = new Spider();


foreach ( $images as $url ) {

    $spider->downloadImage($url);

}

发送XML数据

function senXml($url,$xmlData)
    {
        $header[] = "Content-type: text/xml"; //定义content-type为xml,注意是数组

        $ch = curl_init ($url);

        curl_setopt($ch, CURLOPT_URL, $url);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);

        curl_setopt($ch, CURLOPT_HTTPHEADER,$header);

        curl_setopt($ch, CURLOPT_POST, 1);

        curl_setopt($ch,CURLOPT_POSTFIELDS, $xmlData);

        $response = curl_exec($ch);

        if(curl_errno($ch)){

            printcurl_error($ch);

        }

        curl_close($ch);
    }

除了curl,还有以下获取数据的请求方式

 /*发送数据  */
   function send_post($url, $post_data)
   {
       $postdata = http_build_query($post_data);
       $options = array(
           'http' => array(
               'method' => 'POST',
               'header' => 'Content-type:application/x-www-form-urlencoded',
               'content' => $postdata,
               'timeout' => 15 * 60
           ) // 超时时间(单位:s)

       );
       $context = stream_context_create($options);
       $result = file_get_contents($url, false, $context);
       return $result;
   }

以下这种方式请求得到xml格式数据

我不知道自己的MAC环境为什么不可行,但是有朋友的linuxwin是可以的。

function get1($dataStr){
       $xhr = new COM("MSXML2.XMLHTTP"); 
       $xhr->open("GET",$dataStr,false); 
       $xhr->send();
       $res=$xhr->responseText;
       return $res; 
    }
 function postCurl($data)
    {
        $ch = curl_init(self::conf()['api_url']);
        curl_setopt($ch, CURLOPT_POST, true);
// ssl的屏蔽
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        return curl_exec($ch);
    }

你可能感兴趣的:(实用的 CURL 类-访问pc端接口)