views:

256

answers:

3

I am working on my REST client library for CodeIgniter and I am struggling to work out how to send PUT and DELETE arguments in PHP.

In a few places I have seen people using the options:

$this->option(CURLOPT_PUT, TRUE);
$this->option(CURLOPT_POSTFIELDS, $params);

Annoyingly, this seems to do nothing. Is this the correct way to set PUT parameters?

If so, how do I set DELETE parameters?

*$this->option() is part of my library, it simply builds up an array of CURLOPT_XX constants and sends them to curl_setopt_array() when the built up cURL request is executed.*

I am attempting to read PUT and DELETE parameters using the following code:

        case 'put':
            // Set up out PUT variables
            parse_str(file_get_contents('php://input'), $this->_put_args);
        break;

        case 'delete':
            // Set up out PUT variables
            parse_str(file_get_contents('php://input'), $this->_delete_args);
        break;

There are two options here, I am approaching this in the wrong way or there is a bug somewhere in my libraries. If you could let me know if this should theoretically work I can just hammer away on debug until I solve it.

I dont want to waste any more time on an approach that is fundamentally wrong.

+1  A: 

I think you're mixing your verbs - PUT is for putting a file, POST is for posting variables (although you can POST a file).

To set the post variables, use CURLOPT_POSTFIELDS with either a string of param1=val1&param2=val2 or an associative array.

To do a DELETE, you'll want to use the curl option CURLOPT_CUSTOMREQUEST

adam
PUT and DELETE both support the sending of additional arguments. You can do this via the command line when working with curl but I cannot work out how to send with PHP-cURL.For example, as this is for REST, I need a way to mark what I am deleting. If I am deleting user id, I want to be able to pass the id without cluttering the URL. API's like Twitter only support GET/POST so you can put that in the URL, but other REST API's may not support this sort of thing, so I need to send a delete parameter for it.
Phil Sturgeon
Ok I have PUT parameters working, I swapped CURLOPT_PUT = TRUE for CURLOPT_CUSTOMREQUEST = 'PUT' and thats working fine. Now, how the hell do I set DELETE?
Phil Sturgeon
CURLOPT_CUSTOMREQUEST = 'DELETE', then use query string for the parameters maybe
adam
Close, I was trying to avoid using them in the query string as I have already mentioned. Turns out you can use CURLOPT_POSTFIELDS with PUT and DELETE when using CURLOPT_CUSTOMREQUEST = 'DELETE. Thanks for your feedback, but I solved it myself in the end :-)
Phil Sturgeon
Did you? I didn't help at all then?
adam
Just to clarify PUT / POST act on resources, not necessarily files. The difference being POST is not idempotent, while GET, PUT, and DELETE should be.
Owen
+2  A: 

Instead of using CURLOPT_PUT = TRUE use CURLOPT_CUSTOMREQUEST = 'PUT' and CURLOPT_CUSTOMREQUEST = 'DELETE' then just set values with CURLOPT_POSTFIELDS.

Works perfectly!

Phil Sturgeon
+2  A: 

Just remember, most webservers do not handle PUT & DELETE requests. Since you're making a library, I'd suggest thinking about accounting for this. Typically, there are two conventions you can use to mimic PUT & DELETE via POST.

  1. use a custom POST variable (ex. _METHOD=PUT) which overrides POST
  2. set a custom HTTP header (ex. X-HTTP-Method-Override: PUT)

Generally speaking, most RESTful services that don't allow PUT & DELETE directly will support at least one of those strategies. You can use cURL to set a custom header if you need via the CURLOPT_HTTPHEADER option.

// ex...
curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-HTTP-Method-Override: PUT') );
Owen
Great addidtion, thanks Owen.
Phil Sturgeon