ZetCode

PHP curl_multi_getcontent 函数

最后修改日期:2025 年 4 月 11 日

PHP curl_multi_getcontent 函数在使用 multi 接口时,用于从 cURL 句柄中检索内容。它用于在执行多个并行 cURL 请求后获取响应数据。

基本定义

如果设置了 CURLOPT_RETURNTRANSFERcurl_multi_getcontent 函数将返回 cURL 句柄的内容。它与 cURL multi 接口配合用于并行请求。

语法:curl_multi_getcontent(CurlHandle $handle): ?string。句柄必须是 multi 句柄执行的一部分。如果没有可用内容则返回 NULL,失败则返回 FALSE。

基础多请求

此示例演示了发出两个并行请求并获取其内容。

basic_multi.php
<?php

declare(strict_types=1);

$urls = [
    "https://jsonplaceholder.typicode.com/posts/1",
    "https://jsonplaceholder.typicode.com/posts/2"
];

$mh = curl_multi_init();
$handles = [];

foreach ($urls as $url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_multi_add_handle($mh, $ch);
    $handles[] = $ch;
}

$running = null;
do {
    curl_multi_exec($mh, $running);
} while ($running);

foreach ($handles as $ch) {
    $content = curl_multi_getcontent($ch);
    echo $content . "\n";
    curl_multi_remove_handle($mh, $ch);
    curl_close($ch);
}

curl_multi_close($mh);

此代码创建了两个并行请求来获取帖子。我们使用 curl_multi_exec 同时处理它们。执行后,我们使用 curl_multi_getcontent 检索每个响应。始终正确清理句柄。

处理多个 JSON 响应

此示例展示了如何处理并行请求的多个 JSON 响应。

multi_json.php
<?php

declare(strict_types=1);

$userIds = [1, 2, 3];
$mh = curl_multi_init();
$handles = [];

foreach ($userIds as $id) {
    $url = "https://jsonplaceholder.typicode.com/users/{$id}";
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_multi_add_handle($mh, $ch);
    $handles[$id] = $ch;
}

$running = null;
do {
    curl_multi_exec($mh, $running);
} while ($running);

$results = [];
foreach ($handles as $id =>  $ch) {
    $content = curl_multi_getcontent($ch);
    $results[$id] = json_decode($content, true);
    curl_multi_remove_handle($mh, $ch);
    curl_close($ch);
}

curl_multi_close($mh);

print_r($results);

我们并行获取三个用户记录。每个响应都从 JSON 解码并存储在一个数组中。结果与原始用户 ID 保持关联。这展示了高效的 API 数据批量处理。

多请求中的错误处理

此示例演示了多个 cURL 请求的正确错误处理。

multi_error.php
<?php

declare(strict_types=1);

$urls = [
    "https://jsonplaceholder.typicode.com/posts/1",
    "https://invalid.url",
    "https://jsonplaceholder.typicode.com/comments/1"
];

$mh = curl_multi_init();
$handles = [];

foreach ($urls as $i =>  $url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_multi_add_handle($mh, $ch);
    $handles[$i] = $ch;
}

$running = null;
do {
    curl_multi_exec($mh, $running);
} while ($running);

foreach ($handles as $i =>  $ch) {
    $content = curl_multi_getcontent($ch);
    $error = curl_error($ch);
    
    if ($error) {
        echo "Request {$i} failed: {$error}\n";
    } else {
        echo "Request {$i} succeeded:\n";
        echo substr($content, 0, 100) . "...\n";
    }
    
    curl_multi_remove_handle($mh, $ch);
    curl_close($ch);
}

curl_multi_close($mh);

我们处理三个 URL,其中一个 URL 被故意设为无效。对于每个请求,我们使用 curl_error 检查错误。该示例展示了如何在批量操作中处理成功和失败的请求。

为多请求设置自定义选项

此示例展示了如何为批量中的每个请求设置不同的选项。

multi_options.php
<?php

declare(strict_types=1);

$requests = [
    [
        'url' =>  'https://jsonplaceholder.typicode.com/posts/1',
        'method' =>  'GET'
    ],
    [
        'url' =>  'https://jsonplaceholder.typicode.com/posts',
        'method' =>  'POST',
        'data' =>  ['title' =>  'foo', 'body' =>  'bar', 'userId' =>  1]
    ]
];

$mh = curl_multi_init();
$handles = [];

foreach ($requests as $req) {
    $ch = curl_init($req['url']);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
    if ($req['method'] === 'POST') {
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $req['data']);
    }
    
    curl_multi_add_handle($mh, $ch);
    $handles[] = $ch;
}

$running = null;
do {
    curl_multi_exec($mh, $running);
} while ($running);

foreach ($handles as $i =>  $ch) {
    $content = curl_multi_getcontent($ch);
    echo "Response {$i}:\n";
    echo $content . "\n\n";
    curl_multi_remove_handle($mh, $ch);
    curl_close($ch);
}

curl_multi_close($mh);

我们并行执行 GET 和 POST 请求。在将每个句柄添加到 multi 句柄之前,都会配置其特定选项。这显示了 multi 接口对于不同请求类型的灵活性。

处理大量请求

此示例演示了如何高效地处理大量批量请求。

large_batch.php
<?php

declare(strict_types=1);

// Generate 10 URLs to fetch
$urls = array_map(
    fn($id) =>  "https://jsonplaceholder.typicode.com/posts/{$id}",
    range(1, 10)
);

$mh = curl_multi_init();
$handles = [];
$results = [];
$concurrency = 5; // Process 5 at a time

foreach ($urls as $i =>  $url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 15);
    curl_multi_add_handle($mh, $ch);
    $handles[$i] = $ch;
    
    // Process in batches to avoid overwhelming the system
    if (count($handles) % $concurrency === 0) {
        $running = null;
        do {
            curl_multi_exec($mh, $running);
        } while ($running);
        
        // Process completed requests
        foreach ($handles as $j =>  $ch) {
            if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) {
                $results[$j] = curl_multi_getcontent($ch);
            }
            curl_multi_remove_handle($mh, $ch);
            curl_close($ch);
        }
        
        $handles = [];
    }
}

// Process any remaining handles
if (!empty($handles)) {
    $running = null;
    do {
        curl_multi_exec($mh, $running);
    } while ($running);
    
    foreach ($handles as $j =>  $ch) {
        if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) {
            $results[$j] = curl_multi_getcontent($ch);
        }
        curl_multi_remove_handle($mh, $ch);
        curl_close($ch);
    }
}

curl_multi_close($mh);

echo "Fetched " . count($results) . " responses\n";

此示例以 5 个为一批处理 10 个 URL,以更好地管理资源。我们在存储结果之前检查 HTTP 状态码。该方法可防止在处理大量请求时出现系统过载。结果保持其原始顺序,方便参考。

最佳实践

来源

PHP curl_multi_getcontent 文档

本教程涵盖了 PHP curl_multi_getcontent 函数,并通过实际示例展示了其在并行 HTTP 请求处理中的用法。

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在教授编程方面拥有十多年的经验。

所有 PHP cURL 教程列表。