PHP curl_exec函数

定义和用法

curl_exec() 函数用于执行一个cURL会话。这个函数应该在初始化cURL会话并设置所有选项后调用,它会发送HTTP请求并返回获取的内容。

提示: 在执行curl_exec()之前,必须使用curl_init()初始化会话,并使用curl_setopt()或curl_setopt_array()设置必要的选项。

语法

mixed curl_exec ( resource $ch )

参数

参数 描述 类型 必需
ch curl_init() 返回的cURL句柄 resource

返回值

成功时返回 TRUE 或获取的内容,失败时返回 FALSE

具体返回值取决于 CURLOPT_RETURNTRANSFER 选项的设置:

  • 如果 CURLOPT_RETURNTRANSFER 设置为 TRUE,则返回获取的内容字符串
  • 如果 CURLOPT_RETURNTRANSFER 设置为 FALSE,则直接输出内容并返回 TRUE
  • 如果发生错误,返回 FALSE

cURL工作流程

1
curl_init()
初始化会话
2
curl_setopt()
设置选项
3
curl_exec()
执行请求
4
curl_close()
关闭会话

示例

示例 1:基本的GET请求

@php
    // 初始化cURL会话
    $ch = curl_init();

    // 设置选项
    curl_setopt_array($ch, [
        CURLOPT_URL => "https://api.example.com/data",
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 30
    ]);

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

    // 检查是否出错
    if ($response === false) {
        echo 'cURL Error: ' . curl_error($ch);
    } else {
        // 处理响应
        echo "请求成功!响应长度: " . strlen($response) . " 字节";
    }

    // 关闭会话
    curl_close($ch);
@endphp

示例 2:带错误处理的完整请求

@php
    function makeCurlRequest($url, $options = []) {
        // 初始化cURL
        $ch = curl_init();

        // 默认选项
        $defaultOptions = [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_SSL_VERIFYPEER => false
        ];

        // 合并选项
        $finalOptions = $options + $defaultOptions;

        // 设置选项
        curl_setopt_array($ch, $finalOptions);

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

        // 获取请求信息
        $info = curl_getinfo($ch);
        $error = curl_error($ch);
        $errno = curl_errno($ch);

        // 关闭会话
        curl_close($ch);

        // 返回结果
        return [
            'success' => ($response !== false && $errno === 0),
            'response' => $response,
            'info' => $info,
            'error' => $error,
            'errno' => $errno
        ];
    }

    // 使用函数发送请求
    $result = makeCurlRequest("https://jsonplaceholder.typicode.com/posts/1");

    if ($result['success']) {
        $data = json_decode($result['response'], true);
        echo "请求成功!HTTP状态码: " . $result['info']['http_code'] . "\n";
        echo "标题: " . $data['title'];
    } else {
        echo "请求失败: " . $result['error'];
    }
@endphp

示例 3:POST请求与数据处理

@php
    // 准备POST数据
    $postData = [
        'title' => 'My Post Title',
        'body' => 'This is the content of my post.',
        'userId' => 1
    ];

    $ch = curl_init();

    curl_setopt_array($ch, [
        CURLOPT_URL => "https://jsonplaceholder.typicode.com/posts",
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => json_encode($postData),
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Content-Length: ' . strlen(json_encode($postData))
        ],
        CURLOPT_TIMEOUT => 30
    ]);

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

    if ($response === false) {
        echo "POST请求失败: " . curl_error($ch);
    } else {
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if ($httpCode >= 200 && $httpCode < 300) {
            $createdPost = json_decode($response, true);
            echo "POST请求成功!创建的文章ID: " . $createdPost['id'];
        } else {
            echo "POST请求完成,但HTTP状态码为: " . $httpCode;
        }
    }

    curl_close($ch);
@endphp

示例 4:文件下载

@php
// 下载文件到本地
$fileUrl = "https://www.example.com/sample.pdf";
$localFile = "/path/to/downloads/sample.pdf";

$ch = curl_init();

curl_setopt_array($ch, [
    CURLOPT_URL => $fileUrl,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_BINARYTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_TIMEOUT => 60, // 文件下载可能需要更长时间
    CURLOPT_SSL_VERIFYPEER => false
]);

// 执行下载
$fileContent = curl_exec($ch);

if ($fileContent !== false) {
    // 保存文件
    if (file_put_contents($localFile, $fileContent) !== false) {
        echo "文件下载成功!保存到: " . $localFile;

        // 获取文件信息
        $fileSize = curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD);
        $downloadSpeed = curl_getinfo($ch, CURLINFO_SPEED_DOWNLOAD);
        echo "文件大小: " . round($fileSize / 1024, 2) . " KB";
        echo "下载速度: " . round($downloadSpeed / 1024, 2) . " KB/s";
    } else {
        echo "文件保存失败!";
    }
} else {
    echo "文件下载失败: " . curl_error($ch);
}

curl_close($ch);
@endphp

常见问题与解决方案

问题 症状 解决方案
返回FALSE curl_exec()返回false,无法获取内容 使用curl_error()和curl_errno()获取错误信息
超时问题 请求长时间无响应或超时 设置CURLOPT_TIMEOUT和CURLOPT_CONNECTTIMEOUT选项
SSL证书问题 HTTPS请求失败,证书验证错误 设置CURLOPT_SSL_VERIFYPEER为false(仅开发环境)
内存问题 大文件下载时内存耗尽 使用CURLOPT_FILE将响应直接写入文件
重定向问题 无法跟随重定向 设置CURLOPT_FOLLOWLOCATION为true

性能优化建议

设置超时

合理设置CURLOPT_TIMEOUT和CURLOPT_CONNECTTIMEOUT,避免长时间等待。

内存优化

对于大文件,使用CURLOPT_FILE直接写入文件,避免内存占用。

连接复用

对于多个请求到同一主机,考虑使用curl_multi_*函数。

压缩传输

设置CURLOPT_ENCODING启用gzip压缩,减少数据传输量。

注意事项

重要:
  • 始终检查curl_exec()的返回值,不要假设请求总是成功
  • 使用curl_error()和curl_errno()来获取详细的错误信息
  • 在生产环境中设置合适的超时时间
  • 及时调用curl_close()释放资源
  • 对于敏感数据,确保使用HTTPS并验证SSL证书
  • 处理大文件时注意内存使用情况