Help me understand CURLOPT_READFUNCTION Help me understand CURLOPT_READFUNCTION curl curl

Help me understand CURLOPT_READFUNCTION


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:

  • $ch is the cURL resource that calls the ReadFunction
  • $fh is the file handle from CURLOPT_INFILE
  • $length is the amount of data it expects to get back.

It returns data from the file of $length length or '' if EOF.


The manual appears to be wrong here:

CURLOPT_READFUNCTION The 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):

  • The first is the curl handle.
  • The second is the PHP stream that set through the option CURLOPT_INFILE.
  • The third is the amount of data that should be read from the PHP stream and passed to the curl library so it can send it to the HTTP server.

EDIT: Fixed in this commit.