zoukankan      html  css  js  c++  java
  • 比 file_get_contents() 更优的 cURL 详解(附实例)

     

    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,内容如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <?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 请求需要设置两个选项:

    1
    2
    curl_setopt($ch, CURLOPT_POST, 1); // 表明POST请求
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postData)); // POST提交数据

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

    1
    2
    3
    4
    <?php
        $input file_get_contents('php://input');
        echo $input;
    ?>

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <?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,显示如下:

    1
    fname=Daniel&lname=Stenberg

    六、实例3.上传文件

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <?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, 脚本内容如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    <?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,显示如下:

    1
    上传成功

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

    七、实例4.下载文件

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    <?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,显示如下:

    1
    下载成功

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

    八、实例5.批处理

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    <?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);
    ?>

    浏览器访问 localserver.com/index.php,显示了“连在一起”的百度首页和起点网首页。

    转载:https://www.cnblogs.com/mingc/p/7425321.html

  • 相关阅读:
    一个很实用的css3兼容工具很多属性可以兼容到IE6
    html5 canvas 填充渐变形状
    找到任何形状的中心-总结篇
    html canvas非正方旋转和缩放...写的大多是正方的有人表示一直看正方的看厌了
    把jQuery的类、插件封装成seajs的模块的方法
    那些年实用但被我忘掉javascript属性.onresize
    总有一些实用javascript的元素被人遗忘在角落-slice
    jquery(入门篇)无缝滚动
    html5 canvas旋转+缩放
    今天看到这篇新闻之后,决定休息一下咯
  • 原文地址:https://www.cnblogs.com/lxwphp/p/11176806.html
Copyright © 2011-2022 走看看