PHP 教程:cURL 函数详解

· PHP笔记 API 小技巧 PHP 入门笔记 · 1 阅读 · 约 10 分钟

前言

cURL 是 PHP 中最常用的网络请求工具,可以模拟浏览器向远程服务器发起 HTTP 请求,常用于调用第三方 API、抓取网页、上传下载文件等场景。本文基于 libcurl 扩展,整理常用函数和参数。

基本流程

使用 cURL 固定四步:初始化、设置选项、执行、关闭。

<?php
// 1. 初始化
$ch = curl_init();

// 2. 设置选项
curl_setopt($ch, CURLOPT_URL, 'https://example.com/api');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回结果而不是直接输出

// 3. 执行请求
$response = curl_exec($ch);

// 4. 关闭句柄
curl_close($ch);
echo $response;

CURLOPT_RETURNTRANSFER 必须重点记住:设为 true 时 curl_exec 返回字符串;不设置则直接把结果打印到页面。

常用选项详解

基础选项

curl_setopt($ch, CURLOPT_URL, 'https://example.com');   // 请求地址
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);         // 以字符串返回结果
curl_setopt($ch, CURLOPT_HEADER, false);                // 是否返回响应头
curl_setopt($ch, CURLOPT_TIMEOUT, 10);                  // 整个请求超时秒数
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);            // 连接超时秒数
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);         // 跟随 302 跳转
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0');     // 自定义 UA
curl_setopt($ch, CURLOPT_REFERER, 'https://example.com'); // 伪造 referer

GET 请求

GET 参数直接拼在 URL 上:

<?php
$data = ['name' => 'Tom', 'age' => 20];
$url = 'https://example.com/api?' . http_build_query($data);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

POST 请求

<?php
$ch = curl_init('https://example.com/api');
$postData = ['username' => 'admin', 'password' => '123456'];
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => http_build_query($postData), // 表单方式
    CURLOPT_RETURNTRANSFER => true,
]);

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

两种 POSTFIELDS 写法的区别:

  • 传字符串(http_build_query 后):Content-Type 为 application/x-www-form-urlencoded
  • 传数组:multipart/form-data,可用于文件上传
  • 传 json_encode 后的字符串:需手动设置 JSON 头
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => json_encode($data, JSON_UNESCAPED_UNICODE),
    CURLOPT_HTTPHEADER     => [
        'Content-Type: application/json',
        'Content-Length: ' . strlen(json_encode($data)),
    ],
]);

自定义请求头

curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer your_token',
    'Accept: application/json',
]);
curl_setopt($ch, CURLOPT_COOKIE, 'name=Tom; age=20');
// 或从文件读取
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookie.txt');

HTTPS 证书问题

本地调试遇到 SSL 证书报错时,可临时关闭验证(生产环境不建议):

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);

正确做法是下载 CA 证书并指定:

curl_setopt($ch, CURLOPT_CAINFO, '/etc/ssl/certs/cacert.pem');

获取响应信息与错误处理

curl_getinfo 可以拿到状态码、耗时等信息;curl_error 用于排错:

<?php
$ch = curl_init('https://example.com/api');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);

if ($response === false) {
    echo 'cURL 错误: ' . curl_error($ch);
} else {
    $info = curl_getinfo($ch);
    echo '状态码: ' . $info['http_code'] . PHP_EOL;
    echo '总耗时: ' . $info['total_time'] . ' 秒' . PHP_EOL;
    echo $response;
}

curl_close($ch);

注意判断要用 === false,因为返回空字符串也可能是合法响应。

上传文件

<?php
// PHP 5.5+ 推荐使用 CURLFile
$ch = curl_init('https://example.com/upload');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
    'file' => new CURLFile('/tmp/test.jpg', 'image/jpeg', 'test.jpg'),
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
echo curl_exec($ch);
curl_close($ch);

封装一个通用 GET/POST 函数

<?php
function http(string $url, array $data = [], string $method = 'GET'): string
{
    $ch = curl_init();
    $opts = [
        CURLOPT_URL            => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_SSL_VERIFYPEER => false,
    ];

    if (strtoupper($method) === 'POST') {
        $opts[CURLOPT_POST]       = true;
        $opts[CURLOPT_POSTFIELDS] = http_build_query($data);
    } else {
        $opts[CURLOPT_URL] = $url . (strpos($url, '?') === false ? '?' : '&')
                           . http_build_query($data);
    }

    curl_setopt_array($ch, $opts);
    $response = curl_exec($ch);
    curl_close($ch);
    return $response ?: '';
}

// 使用示例
echo http('https://example.com/api', ['id' => 1]);
echo http('https://example.com/api', ['name' => 'Tom'], 'POST');

常见问题排查

  • 返回 false:先用 curl_error 看错误信息,多数是 SSL 证书或超时问题
  • 中文乱码:确认对方接口返回编码,必要时 mb_convert_encoding 转换
  • POST 拿不到数据:检查 Content-Type 是否与发送格式匹配
  • 302 后拿不到结果:加上 CURLOPT_FOLLOWLOCATION => true

小结

cURL 的核心就是 curl_init、curl_setopt、curl_exec、curl_close 四步,其余全是 CURLOPT_* 参数的组合。掌握 GET、POST、JSON、文件上传这几类典型写法,再配合 curl_error 和 curl_getinfo 排错,基本可以应对所有 HTTP 请求场景。