Помогите мне понять CURLOPT_READFUNCTION - PullRequest
4 голосов
/ 11 апреля 2011

Я хочу правильно понять CURLOPT_READFUNCTION.

Я смотрю на код Rackspace coudfiles (REST API).

Имеет следующую строку.

curl_setopt($ch, CURLOPT_READFUNCTION, array(&$this, '_read_cb'));

Глядя на определение этой функции:

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;
}

Можете ли вы помочь мне понять, какие значения передаются в $ fd и $ length?

Я хочу указать значение $ length для отправки файла кусками.

Заранее спасибо.

Ответы [ 2 ]

5 голосов
/ 13 марта 2013

Я знаю, что это немного некро, но другие люди могут захотеть узнать, как это работает.

Вот как будет выглядеть типичный блок размещения файла curl:

$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);

и функция чтения выглядела бы примерно так (эта функция регулирует скорость, определяемую пользователем $ 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);
}

Где:

  • $ ch - это ресурс cURL, который вызывает функцию ReadFunction
  • $ fh - это дескриптор файла из CURLOPT_INFILE
  • $ length - это объем данных, которые он ожидает получить.

Возвращает данные из файла длины $ length или '', если EOF.

3 голосов
/ 11 апреля 2011

Руководство здесь выглядит неправильно:

CURLOPT_READFUNCTION Имя функции обратного вызова, в которой функция обратного вызова принимает два параметра.Первый - это ресурс cURL, а второй - строка с данными, которые нужно прочитать.Данные должны быть прочитаны с помощью этой функции обратного вызова.Вернуть количество прочитанных байтов.Возврат 0 к сигналу EOF.

На самом деле требуется три параметра (см. исходный код ):

  • Первым является дескриптор скручивания.
  • Второй - это поток PHP, который задается с помощью опции CURLOPT_INFILE.
  • Третий - это объем данных, который следует прочитать из потока PHP и передать в библиотеку curl, чтобы он моготправить его на HTTP-сервер.

РЕДАКТИРОВАТЬ: Исправлено в этом коммит .

...