7

概述

简介

在设计之初,cURL (Client URL Library)是一种作为使用 URL 语法传输数据的命令行工具。通过 cURL 库,我们可以在 PHP 脚本中自由地使用某种协议来获取或者提交数据,比如获取 HTTP 请求数据。简单的来说,cURL 是客户端向服务器请求资源的工具。

PHP 支持 Daniel Stenberg 创建的 libcurl 库,能够连接通讯各种服务器、使用各种协议。libcurl 目前支持的协议有 http、https、ftp、gopher、telnet、dict、file、ldap。 libcurl 同时支持 HTTPS 证书、HTTP POST、HTTP PUT、 FTP 上传(也能通过 PHP 的 FTP 扩展完成)、HTTP 基于表单的上传、代理、cookies、用户名+密码的认证。

优势

在 PHP 中,想要获取某个 URL 的内容其实很简单,有多种实现方法,比如使用 file_get_contents() 函数:

<?php
$content = file_get_contents("https://segmentfault.com");
var_dump($content);

虽然 file_get_contents() 函数使用起来很方便,但是不够灵活,也没法进行错误处理。在一些复杂的请求中,不能够设置请求头、Cookie、代理、认证等相关信息,更不能向某个服务器提交表单数据,上传文件。

cURl 库不但支持丰富的网络协议,而且提供了设置各种 URL 请求参数的方法,功能强大。cURL 的使用场景有很多,比如访问网页资源,获取 WebService 接口数据、下载 FTP 服务器文件。

使用

基本步骤

要使用 cURL 来发送 URL 请求,步骤大体分为以下四步:

  1. 初始化 cURL 会话;
  2. 设置请求选项;
  3. 执行 cURL 会话;
  4. 关闭 cURL 会话。
// 1. 初始化 cURL 会话
$ch = curl_init();

// 2. 设置请求选项
curl_setopt($ch, CURLOPT_URL, "https://segmentfault.com");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); # 获取的信息以字符串返回,而不是直接输出
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); # 禁止 cURL 验证对等证书,从而支持 HTTPS 访问

// 3. 执行 cURL 会话
$response = curl_exec($ch);
var_dump($response);

// 4. 关闭 cURL 会话
curl_close($ch);
cURL 主要通过 curl_setopt() 函数设置请求选项,具体的每个选项说明请见 http://php.net/manual/zh/func...

错误处理

通过 curl_error() 函数可以查看 cURL 会话错误详情,而 curl_getinfo() 函数可以查看响应信息。因此,通过这两个函数我们可以实现一个简单的错误处理程序,比如我们现在访问一个不存在的 URL 地址:

<?php

// 1. 初始化 cURL 会话
$ch = curl_init();

// 2. 设置请求选项
curl_setopt($ch, CURLOPT_URL, "https://segmentfault.com/test.php"); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); # 获取的信息以字符串返回,而不是直接输出
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); # 禁止 cURL 验证对等证书,从而支持 HTTPS 访问

// 3. 执行 cURL 会话
$response = curl_exec($ch);

if ($response  === FALSE) {
    echo "cURL connert error: " . curl_error($ch);
    exit;
}

$info = curl_getinfo($ch);
if ($info['http_code'] == 404) {
    echo 'HTTP 404';
    exit;
}

var_dump($response);

// 4. 关闭 cURL 会话
curl_close($ch);

实战案例

1. POST 请求

使用 cURL 模拟发送 POST 请求:

<?php
function curl_post($url, $data) {
    $ch = curl_init(); 

    curl_setopt_array($ch, [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => 1, # 获取的信息以字符串返回
        CURLOPT_POST => 1,           # 发送 POST 请求
        CURLOPT_POSTFIELDS => $data, # POST 请求数据 
    ]);

    $response = curl_exec($ch);
    
    curl_close($ch);
    
    return $response;
}

$url  = 'http://localhost/test.php';
$data = ['id' => 1, 'username' => 'jochen'];
echo curl_post($url, $data);

2. 文件上传

CURLOPT_POSTFIELDS:全部数据使用 HTTP 协议中的 "POST" 操作来发送。 要发送文件,在文件名前面加上@前缀并使用完整路径。 文件类型可在文件名后以 ';type=mimetype' 的格式指定。 这个参数可以是 urlencoded 后的字符串,类似'val1=1&val2=2&...',也可以使用一个以字段名为键值,字段数据为值的数组。

通过 cURL 发送 POST 请求来实现文件上传:

<?php
function curl_upload($url, $data) {
    $ch = curl_init(); 

    curl_setopt_array($ch, [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => 1, # 获取的信息以字符串返回
        CURLOPT_POST => 1,           # 发送 POST 请求
        CURLOPT_POSTFIELDS => $data, # POST 请求数据 
    ]);

    $response = curl_exec($ch);
    
    curl_close($ch);
    
    return $response;
}

$url  = 'http://localhost/test.php';
$data = ['id' => 1, 'file' => '@/root/image/boy.jpg'];
echo curl_post($url, $data);

3. 文件下载

其实,文件下载与普通 GET 请求是一样的,只是文件下载把返回内容保存至文件中,而不是简单的输出。配合 file_put_contents() 函数实现文件下载:

<?php
function curl_download($url, $path) {
    $ch = curl_init(); 

    curl_setopt_array($ch, [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => 1, # 获取的信息以字符串返回
    ]);

    $response = curl_exec($ch);
    
    curl_close($ch);
    
    return file_put_contents($path, $response);
}

curl_download('http://localhost/boy.jpg', './boy.jpg');

4. HTTP 认证

如果服务器端需要验证请求,设置 CURLOPT_USERPWD 参数即可:

<?php
function curl_auth($url, $user, $passwd) {
    $ch = curl_init();
    
    curl_setopt_array($ch, [
        CURLOPT_URL => $url,
        CURLOPT_USERPWD => "$user:$passwd", # 格式为:"[username]:[password]"
        CURLOPT_RETURNTRANSFER => 1
    ]);
    
    $result = curl_exec($ch);
    
    curl_close($ch);
    
    return $result;
}

echo curl_auth('http://localhost', 'jochen', 'password');

5. 模拟登录

这里主要展示模拟登录使用了 Cookie 来保持登录状态的应用。首先我们需要通过账号密码登录获取到 Cookie 数据,然后利用已登录的 Cookie 获取页面数据:

<?php
// 模拟登录获取 Cookie
function curl_login($url, $data, $cookie) {
    $ch = curl_init(); 

    curl_setopt_array($ch, [
        CURLOPT_URL => $url,
        CURLOPT_POST => 1,           # 发送 POST 请求
        CURLOPT_POSTFIELDS => $data, # POST 请求数据 
        CURLOPT_COOKIEJAR => $cookie # 将 cookie 信息保存至文件中
        CURLOPT_RETURNTRANSFER => 1, # 获取的信息以字符串返回
    ]);

    $response = curl_exec($ch);
    
    curl_close($ch);
    
    return $response;
}

// 获取页面数据
function curl_content($url, $cookie) {
    $ch = curl_init(); 
    
    curl_setopt_array($ch, [
        CURLOPT_URL => $url,
        CURLOPT_COOKIEFILE => $cookie # 加载包含 Cookie 数据的文件
        CURLOPT_RETURNTRANSFER => 1, # 获取的信息以字符串返回
    ]);

    $response = curl_exec($ch);
    
    curl_close($ch);
    
    return $response;
}

$post = ['username' => 'jochen', 'password' => '123456'];
$cookie = './cookie.txt';
if (curl_login('http://localhost/login', $post,  $cookie)) {
    echo curl_content('http://localhost', $cookie);
}

cURL 封装库

PHP Curl Class 是一个编写得很好的 cURL 封装库,它可以非常方便地发送 HTTP 请求并与任何类型的 Web API 集成。PHP Curl Class 封装库适用于 PHP 5.3,5.4,5.5,5.6,7.0,7.1 和 HHVM。这个库是众所周知的,并提供了一个非常简单的语法:

<?php
require __DIR__ . '/vendor/autoload.php';

use \Curl\Curl;

$curl = new Curl();
$curl->get('https://www.example.com/');

if ($curl->error) {
    echo 'Error: ' . $curl->errorCode . ': ' . $curl->errorMessage . "\n";
} else {
    echo 'Response:' . "\n";
    var_dump($curl->response);
}

参考文章:

  1. Client URL 库
  2. php中的curl使用入门教程和常见用法实例
  3. 在PHP中使用CURL,“撩”服务器只需几行——php curl详细解析和常见大坑
  4. Top 7: Best Curl Wrapper Libraries for PHP

Jochen
846 声望85 粉丝

Stay hungry, stay foolish.


« 上一篇
PHP 会话控制
下一篇 »
PHP 运行模式