前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >比 file_get_contents() 更优的 cURL 详解(附实例)

比 file_get_contents() 更优的 cURL 详解(附实例)

作者头像
码农编程进阶笔记
发布2021-07-20 15:20:19
9090
发布2021-07-20 15:20:19
举报

PHP 可以使用 file_get_content() 函数抓取网页内容,但却无法进行更复杂的处理,譬如文件的上传或下载、 Cookie 操作等等。而 cURL 提供了这些功能。

一、cURL简介

在 PHP 中,cURL 是一个扩展库。它可以与各种类型的服务器、使用各种类型的协议进行连接和通讯。

它目前支持 http、https、ftp、gopher、telnet、dict、file 和 ldap 协议,同时也支持 HTTPS 认证、HTTP POST、 FTP 上传、代理、cookies 和 用户名 + 密码的认证等。

二、cURL函数库

常用函数

函数

描述

curl_init()

初始化 cURL 会话

curl_setopt()

设置 cURL 选项

curl_exec()

执行 cURL 会话

curl_getinfo()

获取当前会话信息

curl_errno()

返回最后一次的错误代码

curl_error()

返回当前会话最后一次的错误字符串

curl_close()

关闭 cURL 会话

其他函数

函数

描述

curl_copy_handle()

复制一个 cURL 句柄和它的所有选项。

curl_escape()

返回转义字符串,对给定的字符串进行URL编码。

curl_file_create()

创建一个 CURLFile 对象。

curl_multi_add_handle()

向 cURL 批处理会话中添加单独的curl句柄。

curl_multi_close()

关闭一组 cURL 句柄。

curl_multi_exec()

运行当前 cURL 句柄的子连接。

curl_multi_getcontent()

如果设置了 CURLOPT_RETURNTRANSFER ,则返回获取的输出的文本流。

curl_multi_info_read()

获取当前解析的 cURL 的相关传输信息。

curl_multi_init()

返回一个新 cURL 批处理句柄。

curl_multi_remove_handle()

移除 cURL 批处理句柄资源中的某个句柄资源。

curl_multi_select()

等待所有 cURL 批处理中的活动连接。

curl_multi_setopt()

设置一个批处理 cURL 传输选项。

curl_multi_strerror()

返回描述错误码的字符串文本。

curl_pause()

暂停及恢复连接。

curl_reset()

重置 libcurl 的会话句柄的所有选项。

curl_setopt_array()

为 cURL 传输会话批量设置选项。

curl_share_close()

关闭 cURL 共享句柄。

curl_share_init()

初始化 cURL 共享句柄。

curl_share_setopt()

设置一个共享句柄的 cURL 传输选项。

curl_strerror()

返回错误代码的字符串描述。

curl_unescape()

解码 URL 编码后的字符串。

curl_version()

获取 cURL 版本信息。

三、实现流程

1. 初始化 cURL 会话

2. 设置 cURL 选项

3. 执行 cURL 会话

4. 获取 cURL 信息和(或)错误信息(这一步可以没有)

5. 关闭 cURL 句柄

这里面最复杂的是第 2 步,cURL 的设置选项有很多,下面会结合实例来了解。查看所有选项请看这里:http://www.runoob.com/php/func-curl_setopt.html

四、实例1.GET请求

GET 请求的流程就是 cURL 的一般流程。

在本地服务器 localserver.com 根目录准备一个测试脚本 index.php,内容如下:

代码语言:javascript
复制
<?php
    $url = 'http://www.baidu.com';
 
    // 初始化,获得一个cURL句柄
    $ch = curl_init();
     
    // 设置选项
    curl_setopt($ch, CURLOPT_URL, $url); // 请求URL
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回数据流,而不直接输出
    curl_setopt($ch, CURLOPT_HEADER, 0); // 无需响应的header头
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); //连接超时,单位为秒
 
    // 执行并获取返回内容
    $output = curl_exec($ch);
    if($output === false){
        $output = 'cURL error: ' . curl_error($ch);
    }
 
    // 释放 cURL 句柄资源
    curl_close($ch);
 
    print_r($output);
?>

浏览器访问本地服务器首页 localserver.com/index.php,显示百度首页。

五、实例2.POST请求

POST 请求需要设置两个选项:

代码语言:javascript
复制
curl_setopt($ch, CURLOPT_POST, 1); // 表明POST请求
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData)); // POST提交数据

先在远程服务器 remoteserver.com 根目录准备一个用于接收的脚本 index.php,内容如下:

代码语言:javascript
复制
<?php
    $input = file_get_contents('php://input');
    echo $input;
?>

然后在本地服务器 localserver.com 根目录来写用于 POST 请求的脚本 index.php,内容如下:

代码语言:javascript
复制
<?php
    $url = 'http://remoteserver.com/index.php';
    $data = array(
        'fname'=> 'Daniel',
        'lname' => 'Stenberg'
    );
 
     // 初始化
    $ch = curl_init();
     
    // 设置选项
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch, CURLOPT_POST, 1); // POST请求
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); //POST数据。用http_build_query()转换为“&”拼接的字符串
 
    // 执行并获取返回内容
    $output = curl_exec($ch);
    if($output === false){
        $output =  'cURL error: ' . curl_error($ch);
    }
 
    // 释放 cURL 句柄资源
    curl_close($ch);
 
    print_r($output);
?>

浏览器访问 localserver.com/index.php,显示如下:

代码语言:javascript
复制
fname=Daniel&lname=Stenberg

六、实例3.上传文件

cURL 上传文件的思路是:在文件路径的前面添加"@"符号,并装在请求字段里实现上传。后台可以通过 $_FILES 获取上传文件信息。但 PHP5.6 以后,废除了"@"符号,可以使用 CURLFile 类实现上传。

先在远程服务器 remoteserver.com 根目录准备一个用于接收的脚本 index.php,内容如下:

代码语言:javascript
复制
<?php
    $action = $_POST['action'];
    if($action == 'uploadImage'){
        $name = $_FILES['file']['name'];
        $tmpname = $_FILES['file']['tmp_name'];
         
        // 保存到当前脚本所在目录
        move_uploaded_file($tmpname, dirname(__FILE__).'/'.$name);
 
        $error = $_FILES['file']['error'];
        switch ($error) {
            case 0: echo '上传成功'; break;
            case 1: echo '文件大小超出 php.ini 限制'; break;
            case 2: echo '文件大小超出 表单 MAX_FILE_SIZE 限制'; break;
            case 3: echo '文件部分被上传'; break;
            case 4: echo '没有文件被上传'; break;
            case 6: echo '找不到临时文件夹'; break;
            case 7: echo '文件写入失败'; break;
            default: $output = '未知错误';
        }
    }
?>

然后在本地服务器 localserver.com 根目录准备一个图片文件 test.jpg 和 cURL 上传脚本 index.php, 脚本内容如下:

代码语言:javascript
复制
<?php
    $url = 'http://remoteserver.com/index.php';
    $file = realpath(getcwd() . '/test.jpg');
    $data = array(
        'action' => 'uploadImage',
        'file' => '@' . $file
    );
    if(version_compare(PHP_VERSION, '5.6.0') > 0){
        $data['file'] = new CURLFile($file);
    }
     
    // 初始化
    $ch = curl_init();
     
    // 设置选项
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
 
    // 执行并获取返回内容
    $output = curl_exec($ch);
    if($output === false){
        $output =  'cURL error: ' . curl_error($ch);
    }
 
    // 释放 cURL 句柄资源
    curl_close($ch);
 
    print_r($output);
?>

浏览器访问 localserver.com/index.php,显示如下:

代码语言:javascript
复制
上传成功

查看远程服务器根目录,发现多了一张刚才上传的图片。

七、实例4.下载文件

cURL 下载文件的一个思路是:设置 cURL 选项 CURLOPT_FILE 为一个文件指针,以此将请求的资源文件关联到一个文件流里,这个文件流一般是 fopen()函数的返回值。使用文件流将远程文件写到本地,可以避免写(下载)大文件时可能的内存出错。

在本地服务器 localserver.com 根目录来写测试脚本 index.php,内容如下:

代码语言:javascript
复制
<?php
    $url = 'http://remoteserver.com/test.jpg';
    $file = './test.jpg';
    $fp = fopen($file, 'w');
 
    // 初始化
    $ch = curl_init();
 
    // 设置选项
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch, CURLOPT_FILE, $fp); // 用于传输的文件流,默认是STDOUT
 
    // 执行并获取返回内容
    $output = curl_exec($ch);
    if($output === false){
        $output =  'cURL error: ' . curl_error($ch);
    }
 
    // 获取已下载大小
    $size_download = curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD);
 
    // 释放资源
    fclose($fp);
    curl_close($ch);
 
    if ($size_download && $size_download == filesize($file)) {
        echo "下载成功";
    } else {
        echo "下载失败或不完整";
    }  
?>

浏览器访问 localserver.com/index.php,显示如下:

代码语言:javascript
复制
下载成功

查看本地服务器根目录,发现下载到了远程的图片。 

八、实例5.批处理

cURL 有一个批处理句柄,通过打开多个 cURL 句柄,并将这些句柄绑定到一个批处理句柄,然后在循环中依次处理每个 cURL 连接,可以实现异步的批处理,类似“多线程”。

在本地服务器 localserver.com 根目录来写测试脚本 index.php,内容如下:

代码语言:javascript
复制
<?php
    $urls = array(
        'http://www.baidu.com',
        'http://www.qidian.com'
    );
    $count = count($urls);
    $ch = array();
 
    // 创建批处理cURL句柄
    $mh = curl_multi_init();
 
    // 初始化每个cURL,并设置选项,绑定给批处理句柄
    for ($i = 0; $i < $count; $i++) {
        $ch[$i] = curl_init();
        curl_setopt($ch[$i], CURLOPT_URL, $urls[$i]);
        curl_setopt($ch[$i], CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch[$i], CURLOPT_HEADER, 0);
        curl_setopt($ch[$i], CURLOPT_CONNECTTIMEOUT, 30);
        curl_multi_add_handle($mh, $ch[$i]);
    }
 
    // 执行批处理
    $running = null;
    do {
        usleep(10000); // 延迟0.01秒,单位为百万分之一秒
        curl_multi_exec($mh, $running); // 异步实现批处理,类似“多线程”
    } while($running > 0);
 
    // 获取每个cURL的响应
    $res = array();
    for ($i = 0; $i < $count; $i++) {
        $res[$i] = curl_multi_getcontent($ch[$i]);
    }
 
    // 关闭全部句柄
    for ($i = 0; $i < $count; $i++) {
        curl_multi_remove_handle($mh, $ch[$i]);
    }
    curl_multi_close($mh);
 
    print_r($res);
?>
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农编程进阶笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、cURL简介
  • 二、cURL函数库
  • 三、实现流程
  • 四、实例1.GET请求
  • 五、实例2.POST请求
  • 六、实例3.上传文件
  • 七、实例4.下载文件
  • 八、实例5.批处理
相关产品与服务
命令行工具
腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档