ZetCode

PHP curl_pause 函数

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

PHP curl_pause 函数可以暂停和恢复 cURL 传输。它用于暂时停止正在进行的传输,然后稍后恢复它们。这对于控制带宽或实现自定义传输逻辑非常有用。

基本定义

curl_pause 函数暂停或恢复 cURL 传输。它接受一个 cURL 句柄和一个位掩码参数,指定要暂停的传输。该函数返回错误代码(成功时为 CURLE_OK)。

语法:curl_pause(CurlHandle $handle, int $bitmask): int。位掩码可以组合 CURLPAUSE_RECV、CURLPAUSE_SEND、CURLPAUSE_ALL 或 CURLPAUSE_CONT。始终检查返回值以处理错误。

基本暂停和恢复

本示例演示了如何暂停和恢复简单的下载。

basic_pause.php
<?php

declare(strict_types=1);

$ch = curl_init();
$fp = fopen("download.txt", "w");

curl_setopt($ch, CURLOPT_URL, "https://example.com/largefile");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, function($resource, $download_size, $downloaded, $upload_size, $uploaded) {
    if ($downloaded > 1024 * 1024) { // After 1MB
        return CURLPAUSE_ALL; // Pause both directions
    }
    return CURLPAUSE_CONT; // Continue normally
});

curl_exec($ch);

// Later resume the transfer
curl_pause($ch, CURLPAUSE_CONT);

curl_close($ch);
fclose($fp);

此代码下载一个文件,但在 1MB 后暂停。进度函数返回 CURLPAUSE_ALL 进行暂停。之后,我们使用 CURLPAUSE_CONT 恢复。请注意,文件句柄在暂停期间保持打开状态。

仅暂停接收

本示例展示了如何仅暂停接收操作,同时允许发送。

pause_receive.php
<?php

declare(strict_types=1);

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://api.example.com/stream");
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $data) {
    static $count = 0;
    $count += strlen($data);
    
    if ($count > 5000) {
        return -1; // Triggers pause
    }
    echo $data;
    return strlen($data);
});

curl_exec($ch);

// Check if paused
if (curl_errno($ch) == CURLE_READ_ERROR) {
    // Pause only receiving
    curl_pause($ch, CURLPAUSE_RECV);
    
    // Later resume receiving
    sleep(5);
    curl_pause($ch, CURLPAUSE_CONT);
}

curl_close($ch);

我们使用 WRITEFUNCTION 来处理传入的数据。返回 -1 会暂停传输。然后我们使用 CURLPAUSE_RECV 显式地仅暂停接收。在暂停期间,如果配置正确,发送仍然可以正常工作。

在 Multi cURL 中暂停

本示例演示了在 multi cURL 传输中暂停特定句柄。

multi_pause.php
<?php

declare(strict_types=1);

$mh = curl_multi_init();
$ch1 = curl_init("https://api1.example.com/stream");
$ch2 = curl_init("https://api2.example.com/stream");

curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);

do {
    $status = curl_multi_exec($mh, $active);
    
    if ($active) {
        // Check if we should pause ch1
        $info = curl_getinfo($ch1);
        if ($info['size_download'] > 1024 * 512) { // 512KB
            curl_pause($ch1, CURLPAUSE_ALL);
            echo "Paused first transfer\n";
        }
        
        curl_multi_select($mh);
    }
} while ($status == CURLM_OK && $active);

// Cleanup
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);

在 multi 句柄上下文中,我们可以暂停单个传输。在这里,我们在 512KB 后暂停第一个传输,而第二个传输继续进行。Multi 接口在暂停期间会继续运行。

使用暂停进行速率限制

本示例使用 curl_pause 实现简单的速率限制。

rate_limit.php
<?php

declare(strict_types=1);

$ch = curl_init();
$start_time = microtime(true);
$bytes_received = 0;
$max_rate = 1024 * 50; // 50KB/s

curl_setopt($ch, CURLOPT_URL, "https://example.com/largefile");
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $data) use (&$bytes_received, $start_time, $max_rate) {
    $bytes_received += strlen($data);
    $elapsed = microtime(true) - $start_time;
    $target_time = $bytes_received / $max_rate;
    
    if ($elapsed < $target_time) {
        $sleep = $target_time - $elapsed;
        usleep((int) ($sleep * 1000000));
        return CURLPAUSE_RECV; // Pause receiving
    }
    
    echo $data;
    return strlen($data);
});

curl_exec($ch);
curl_close($ch);

我们计算所需的传输速率,并在进度超前时暂停接收。这创建了一个简单的速率限制器。WRITEFUNCTION 同时处理数据处理和速率控制。

上传期间暂停

本示例展示了如何在上传期间暂停。

upload_pause.php
<?php

declare(strict_types=1);

$ch = curl_init();
$data = str_repeat("test data ", 100000); // Large data

curl_setopt($ch, CURLOPT_URL, "https://api.example.com/upload");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_READFUNCTION, function($ch, $fd, $length) {
    static $sent = 0;
    $chunk = substr($GLOBALS['data'], $sent, $length);
    $sent += strlen($chunk);
    
    if ($sent > 1024 * 100) { // After 100KB
        return ''; // Triggers pause
    }
    return $chunk;
});

curl_exec($ch);

// Check if paused
if (curl_errno($ch) == CURLE_READ_ERROR) {
    echo "Upload paused at 100KB\n";
    sleep(2); // Wait 2 seconds
    curl_pause($ch, CURLPAUSE_CONT); // Resume
    curl_exec($ch); // Continue transfer
}

curl_close($ch);

在上传期间,READFUNCTION 可以通过返回空字符串来触发暂停。然后我们使用 curl_pause 显式恢复。请注意,恢复后我们需要再次调用 curl_exec。

最佳实践

来源

PHP curl_pause 文档

本教程通过实际示例介绍了 PHP curl_pause 函数,展示了其在控制传输方面的用法。

作者

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

所有 PHP cURL 教程列表。