I want to understand CURLOPT_READFUNCTION properly.
I am looking at Rackspace coudfiles php code (REST API).
It has following line.
curl_setopt($ch, CURLOPT_READFUNCTION, array(&$this, '_read_cb'));
Looking at defination of this function:
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;
}
Can you help me understand what values is passed to $fd and $length?
I want to specify $length value specifically, to send file in chunks.
Thanks in advance.
I know this is a bit of a necro - but other people might want to know how this works.
Here's how a typical curl file put block would look:
$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);
and the read function would look something like this (this one throttles to user-defined $goal speed and gives a CLI display feedback)
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);
}
Where:
It returns data from the file of $length length or '' if EOF.
The manual appears to be wrong here:
CURLOPT_READFUNCTIONThe name of a callback function where the callback function takes two parameters. The first is the cURL resource, and the second is a string with the data to be read. The data must be read by using this callback function. Return the number of bytes read. Return 0 to signal EOF.
It actually takes three parameters (see the source code):
CURLOPT_INFILE.EDIT: Fixed in this commit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With