[PHP] CURL 的各种骚使用(GET,POST,上传下载图片,带认证,带COOKIE)

484 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

curl是个什么

curl是一个库,能让你通过URL和许多不同种的服务器进行勾搭和深入交流,并且还支持许多协议。并且人家还说了curl可以支持https认证、http post、ftp上传、代理、cookies、简单口令认证等等功能啦

前提

PHP环境中安装和启用curl模块

说明

  • $ch = curl_init() 创建了一个curl会话资源,成功返回一个句柄;
  • curl_setopt($ch, CURLOPT_URL, "baidu.com"),设置URL;
  • curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0)
    • 1:(存入)将curl_exec()获取的信息以文件流的形式返回,而不是直接输出 在这里插入图片描述
    • 0:(echo)(可有可无)(默认) 如果成功只返回TRUE,自动输出返回的内容 在这里插入图片描述
  • $output = curl_exec($ch)执行,然后将响应结果存入$output变量
  • curl_close($ch)关闭这个curl会话资源

通过curl_setopt方法来设置参数是最复杂也是最重要的

大致用法

创建curl会话 => 配置参数 => 执行 => 关闭会话

GET和POST请求

GET

//通过curl进行GET请求的案例
<?php
    // create curl resource
   $ch = curl_init();
   // set url
   curl_setopt($ch, CURLOPT_URL, "https://github.com/search?q=react");
   //return the transfer as a string
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
   // $output contains the output string
   $output = curl_exec($ch);
   //echo output
   echo $output;
   // close curl resource to free up system resources
   curl_close($ch);
?>
  • 默认GET,所以不需要显式指定GET方式
  • https请求,非http请求
    • CURLOPT_SSL_VERIFYPEER - verify the peer's SSL certificate
    • CURLOPT_SSL_VERIFYHOST - verify the certificate's name against host
  • 除非用了非法或者自制的证书,这大多数出现在开发环境中,你才将这两行设置为false以避开ssl证书检查,否者不需要这么做,这么做是不安全的做法

POST

数组为入参

<?php

    $arrayDta=array(
    "name" => "Lei",
    "msg" => "Are you OK?"
    );
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "http://测试服务器的IP马赛克/testRespond.php");
    curl_setopt($ch, CURLOPT_POST, 1);
    //The number of seconds to wait while trying to connect. Use 0 to wait indefinitely.
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
    // 数组形式为入参需要 http_build_query()处理
    curl_setopt($ch, CURLOPT_POSTFIELDS , http_build_query($arrayDta));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($ch);
    echo $output;
    curl_close($ch); 
?>
  • 结果 name=Lei&msg=Are you OK?
  • 数组形式为入参需要 **http_build_query()**处理 curl_setopt($ch, CURLOPT_POSTFIELDS , http_build_query($arrayDta));

JSON 入参

<?php
    $data='{"name":"Lei","msg":"Are you OK?"}';
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "http://测试服务器的IP马赛克/testRespond.php");
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
    
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Content-Length:' . strlen($data)));
    curl_setopt($ch, CURLOPT_POSTFIELDS , $data);
    
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($ch);
    echo $output;
    curl_close($ch); 
?>
  • 结果 {"name":"Lei","msg":"Are you OK?"}
  • 设置header头 array('Content-Type: application/json', 'Content-Length:' . strlen($data))
  •    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Content-Length:' . strlen($data)));
       curl_setopt($ch, CURLOPT_POSTFIELDS , $data);
    

上传和下载文件

  • POST上传文件

  • <?php
      $data = array('name'=>'boy', "upload"=>"");
      $ch = curl_init();
      $data['upload']=new CURLFile(realpath(getcwd().'/boy.png'));
      curl_setopt($ch, CURLOPT_URL, "http://115.29.247.189/test/testRespond.php");
      curl_setopt($ch, CURLOPT_POST, 1);
      curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
      curl_setopt($ch, CURLOPT_POSTFIELDS , $data);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      $output = curl_exec($ch);
      echo $output;
      curl_close($ch); 
      ?>
    
  • 引入了一个CURLFile对象进行实现,关于此的具体可查阅文档进行了解
  • 抓取远程图片

  • 远程服务器在自己的目录下存放了一个图片叫girl.jpg,地址是web服务器根目录/girl.jpg,现在我要去获取这张照片
  • <?php
      $ch = curl_init();
      $fp=fopen('./girl.jpg', 'w');
      curl_setopt($ch, CURLOPT_URL, "http://远程服务器地址马赛克/girl.jpg");
      curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
      curl_setopt($ch, CURLOPT_FILE, $fp);
      $output = curl_exec($ch);
      $info = curl_getinfo($ch);
      fclose($fp);
      $size = filesize("./girl.jpg");
      if ($size != $info['size_download']) {
         echo "下载的数据不完整,请重新下载";
       } else {
         echo "下载数据完整";
      }
      curl_close($ch); 
      ?>
    
  • curl_getinfo方法,这是一个获取本次请求相关信息的方法,对于调试很有帮助,要善用

HTTP认证

拿到了用户名和密码,我们怎么通过PHP CURL搞定HTTP认证呢

function curl_auth($url,$user,$passwd){
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_USERPWD => $user.':'.$passwd,
        CURLOPT_URL     => $url,
        CURLOPT_RETURNTRANSFER => true
    ]);
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}
$authurl = 'http://要请求HTTP认证的地址';
echo curl_auth($authurl,'vace','passwd');

curl_setopt_array 这个方法可以通过数组一次性设置多个参数,防止有些需要多处设置的出现密密麻麻的curl_setopt方法

利用cookie模拟登陆

分两步
  • 登陆界面通过账号密码登陆,然后获取cookie
  • 利用cookie模拟登陆到信息页面获取信息
<?php
  //设置post的数据 
  $post = array (
    'email' => '账户',
    'pwd' => '密码'
  );
  //登录地址 
  $url = "登陆地址"; 
  //设置cookie保存路径 
  $cookie = dirname(__FILE__) . '/cookie.txt'; 
  //登录后要获取信息的地址 
  $url2 = "登陆后要获取信息的地址"; 
  //模拟登录
  login_post($url, $cookie, $post); 
  //获取登录页的信息 
  $content = get_content($url2, $cookie);
  //删除cookie文件
  @ unlink($cookie);
  var_dump($content);
?>
//模拟登录 
function login_post($url, $cookie, $post) {
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 0);
    curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post));
    curl_exec($curl);
    curl_close($curl);
}
//登录成功后获取数据 
function get_content($url, $cookie) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
    $rs = curl_exec($ch);
    curl_close($ch);
    return $rs;
}

路漫漫其修远兮,吾将上下而求索,加油吧