I’m using a REST API which, among other things, uses the DELETE
method like this:
DELETE /resources/whatever/items/123
To access this using PHP I’m using cURL like this:
self::$curl = curl_init();
curl_setopt_array(self::$curl, array(
CURLOPT_AUTOREFERER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_RETURNTRANSFER => true,
));
As you can see, my cURL instance is static and will be reused for subsequent calls. This works fine when switching between “builtin” request methods. For example, in my get()
method, I do something like this:
curl_setopt_array(self::$curl, array(
CURLOPT_HTTPGET => true,
CURLOPT_URL => self::BASE . 'whatever',
));
and then run curl_exec()
. By explicitly setting the request method via CURLOPT_HTTPGET
, a possible previous CURLOPT_POST
will be cleared.
However, setting CURLOPT_CUSTOMREQUEST
(for example to DELETE
) will override any other builtin request method. That’s fine as long as I want to DELETE
things, but calling for example curl_setopt(self::$curl, CURLOPT_HTTPGET, true)
will not reset the custom method; DELETE
will still be used.
I have tried setting CURLOPT_CUSTOMREQUEST
to null
, false
or the empty string, but this will only result in a HTTP request like
/resources/whatever/items/123
i.e. with the empty string as method, followed by a space, followed by the path.
I know that I could set CURLOPT_CUSTOMREQUEST
to GET
instead and do GET requests without any problems, but I wonder whether there is a possiblity to reset CURLOPT_CUSTOMREQUEST
.
Set CURLOPT_CUSTOMREQUEST to NULL and CURLOPT_HTTPGET to TRUE to reset back to an ordinary GET.
(Shrug ...) And what I wound up doing in my API is to simply, "set it every time." My
POST
routine simply sets a custom-header of"POST"
, and so on. Works great.I found that, once you do set a custom-header, it "sticks." Future calls which then attempt to do ordinary
GET, POST, PUT
start to fail. I experimented with the suggestions listed earlier in this post (with PHP-7), and didn't very-quickly meet with success ... so: "to heck with it, this isn't elegant, but it works."This is actually a bug in PHP, since the original documentation states the following:
Unfortunately, as you can see from the source code, the option value gets cast to a string before it's passed to the underlying library.
Solution
I've written a pull request that addresses the issue and allows for
NULL
to be passed for theCURLOPT_CUSTOMREQUEST
option value.The above patch will take some time to get merged into the project, so until then you would have to explicitly set the method yourself once you start using this option.
Update
The fix has been applied to 5.5.11 and 5.6.0 (beta1).