帮助我理解CURLOPT_READFUNCTION

Mih*_*hir 5 php curl libcurl

我想正确理解CURLOPT_READFUNCTION.

我在看Rackspace coudfiles php代码(REST API).

它有以下几行.

curl_setopt($ch, CURLOPT_READFUNCTION, array(&$this, '_read_cb'));
Run Code Online (Sandbox Code Playgroud)

看看这个函数的定义:

private function _read_cb($ch, $fd, $length)
{
    $data = fread($fd, $length);
    $len = strlen($data);
    if (isset($this->_user_write_progress_callback_func)) {
        call_user_func($this->_user_write_progress_callback_func, $len);
    }
    return $data;
}
Run Code Online (Sandbox Code Playgroud)

你能帮我理解传递给$ fd和$ length的值吗?

我想具体指定$ length值,以块的形式发送文件.

提前致谢.

Poe*_*oet 6

我知道这是一个坏死的 - 但其他人可能想知道这是如何工作的.

以下是典型的curl文件put块的外观:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $ret['Location']);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($ch, CURLOPT_READFUNCTION, 'curlPutThrottle');
curl_setopt($ch, CURLOPT_INFILE, $fh);
curl_setopt($ch, CURLOPT_INFILESIZE, $size);

$ret = curl_exec($ch);
Run Code Online (Sandbox Code Playgroud)

并且read函数看起来像这样(这个限制为用户定义的$ goal速度并给出CLI显示反馈)

function curlPutThrottle($ch, $fh, $length = false)
{
    global $size;
    global $current;
    global $throttle;
    global $start;

    /** Set your max upload speed - here 30mB / minute **/
    $goal = (300*1024*1024)/(60*10);

    if (!$length)
    {
        $length = 1024 * 1024;
    }

    if (!is_resource($fh))
    {
        return 0;
    }

    $current += $length;

    if ($current > $throttle) /** Every meg uploaded we update the display and throttle a bit to reach target speed **/
    {
        $pct = round($current/$size*100);
        $disp =  "Uploading (".$pct."%)  -  ".number_format($current, 0).'/'.number_format($size, 0);
        echo "\r     ".$disp.str_repeat(" ", strlen($disp));
        $throttle += 1024*1024;

        $elapsed = time() - $start;
        $expectedUpload = $goal * $elapsed;

        if ($current > $expectedUpload)
        {
            $sleep = ($current - $expectedUpload) / $goal;
            $sleep = round($sleep);

            for ($i = 1; $i <= $sleep; $i++)
            {
                echo "\r Throttling for ".($sleep - $i + 1)." Seconds   - ".$disp;
                sleep(1);
            }
            echo "\r     ".$disp.str_repeat(" ", strlen($disp));
        }
    }

    if ($current > $size)
    {
        echo "\n";
    }

    return fread($fh, $length);
}
Run Code Online (Sandbox Code Playgroud)

哪里:

  • $ ch是调用ReadFunction的cURL资源
  • $ fh是CURLOPT_INFILE的文件句柄
  • $ length是它希望获得的数据量.

它返回$ length长度文件中的数据,如果是EOF,则返回''.


Art*_*cto 5

手册似乎是错在这里:

CURLOPT_READFUNCTION 回调函数的名称,其中回调函数采用两个参数。第一个是 cURL 资源,第二个是包含要读取的数据的字符串。必须使用此回调函数读取数据。返回读取的字节数。返回 0 以发出 EOF 信号。

它实际上需要三个参数(参见源代码):

  • 第一个是卷曲手柄。
  • 第二个是通过选项设置的 PHP 流CURLOPT_INFILE
  • 第三个是应该从 PHP 流中读取并传递给 curl 库以便它可以将其发送到 HTTP 服务器的数据量。

编辑:在此提交中修复。