HOWTO: Do PUT requests with PHP cURL without writing to a file

bsoremsugar —  November 22, 2011 — 11 Comments

I was helping a partner the other day with an issue they were having in a module they developed for Sugar that is safe to load on our On Demand environment. Here’s the code he was using that was causing issues:

$fh = tmpfile();
fwrite($fh, $update_json);
fseek($fh, 0);
$chlead = curl_init();
curl_setopt($chlead, CURLOPT_URL, $closeOppURL);
curl_setopt($chlead, CURLOPT_USERAGENT, 'SugarConnector/1.4');
curl_setopt($chlead, CURLOPT_VERBOSE, 1);
curl_setopt($chlead, CURLOPT_PUT, true);
curl_setopt($chlead, CURLOPT_INFILE, $fh);
curl_setopt($chlead, CURLOPT_INFILESIZE, strlen($update_json));
curl_setopt($chlead, CURLOPT_RETURNTRANSFER, true);
curl_setopt($chlead, CURLOPT_SSL_VERIFYPEER, 0);
$chleadresult = curl_exec($chlead);
$chleadapierr = curl_errno($chlead);
$chleaderrmsg = curl_error($chlead);
curl_close($chlead);

The problem here is that the tmpfile(), fwrite(), and fseek() functions are not allowed on the OD environment, as we don’t block raw file operations for potential security issues. However, the suggested way of doing PUT requests with cURL implies that you are PUTing a file, and it assumes you are reading a file from the filesystem. In this case however, the PUT payload is being generated as JSON, but to work with cURL it’s wanting you to inefficiently write it to a temporary file in order to send it.

Then I came across this post from esteemed PHP Community member Lorna Jane Mitchell, which showed a techique to get around this. So with help from that post, here’s how we refactored the code to eliminate the extranous file write.

$chlead = curl_init();
curl_setopt($chlead, CURLOPT_URL, $closeOppURL);
curl_setopt($chlead, CURLOPT_USERAGENT, 'SugarConnector/1.4');
curl_setopt($chlead, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length: ' . strlen($update_json)));
curl_setopt($chlead, CURLOPT_VERBOSE, 1);
curl_setopt($chlead, CURLOPT_RETURNTRANSFER, true);
curl_setopt($chlead, CURLOPT_CUSTOMREQUEST, "PUT"); 
curl_setopt($chlead, CURLOPT_POSTFIELDS,$update_json);
curl_setopt($chlead, CURLOPT_SSL_VERIFYPEER, 0);
$chleadresult = curl_exec($chlead);
$chleadapierr = curl_errno($chlead);
$chleaderrmsg = curl_error($chlead);
curl_close($chlead);

The key here is to not use the built-in PUT handling, but instead use the  CURLOPT_CUSTOMREQUEST attribute to specify the request type we want manually, and then the CURLOPT_POSTFIELDS to pass the payload. And this works perfectly for Sugar On Demand, and eliminates the overhead of a filesystem write and read.

11 responses to HOWTO: Do PUT requests with PHP cURL without writing to a file

  1. 

    Why not just use POST?

  2. 

    This was exactly what I needed. Thank you!

  3. 
    PUTting up with myself March 26, 2012 at 2:09 am

    and… after hours of struggling I find the exact brilliant answer i needed. Thank you so incredibly much for this :)

  4. 

    good work

  5. 

    This is great and exactly what I was looking for! Thank you so much.
    Unfortunately there is not much information about HTTP PUT on the web so I was struggling to make my request for quite a while…

  6. 

    Just so everyone knows, the data in the $update_json variable will be available in the $_REQUEST array on the receiving script that is being cURLd to.

  7. 

    sweet :)

  8. 

    Or you could just write to memory – for those that can use fwrite():
    $fp = fopen(‘php://temp/maxmemory:256000′, ‘w’);
    fwrite($fp, $message);
    fseek($fp, 0);

    That’ll write up to 256kb to memory before writing to disk.

  9. 

    Thanks this works great, saves messing about with file nonsense!

  10. 

    Greate work! 10x!!! It really helped me.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s