Igor Kromin |   Consultant. Coder. Blogger. Tinkerer. Gamer.

In my last week's post about Google's broken cURL Lite implementation I alluded to a PHP Twitter library that I've been using. That library was twitter-api-php. On the most part the library is very good, it's simple, it allows you to issue requests to the Twitter API and it doesn't have any bloat. Unfortunately it doesn't work out of the box for an App Engine app that uses cURL Lite.

To address some of these issues, I've created a pull request on twitter-api-php that makes it possible to get TwitterAPIExchange working with cURL Lite error handling, however that was not the only change that was required to get everything working.

What I was trying to do was POST a tweet, using code like this...
$postfields = array(
'status' => $message
$twitter = new \TwitterAPIExchange($settings);
$t = $twitter->buildOauth('https://api.twitter.com/1.1/statuses/update.json', 'POST');
$t = $t->setPostfields($postfields);
$ret = $t->performRequest();

The above was all standard code, pretty much as per the examples. I'm not showing how the $settings array is populated, but that's very straight forward. The problem was, every time I tried to run that code, I'd get this response back from the Twitter API...
{"errors":[{"code":32,"message":"Could not authenticate you."}]}

All of my authentication values in the $settings array were correct however! Something else was wrong. Since I knew that cURL Lite had issues, I started doing more reading and noticed something interesting on the Issuing HTTP(S) Requests page. The $options array that was being passed to curl_setopt_array() had an additional option that TwitterAPIExchange was not setting.

That option was CURLOPT_POST and it was set like this - CURLOPT_POST => count($data). Technically this was a boolean field but I can see what the example from Google was trying to do. I decided to run with it.

Luckily TwitterAPIExchange had a provision for setting your own cURL options, so I changed the performRequest() call to this...
$ret = $t->performRequest(true, [CURLOPT_POST => count($postfields)]);

Bingo! Just like that it started to work!

In standard cURL the CURLOPT_POST option is implied if CURLOPT_POSTFIELDS is set. Looks like in cURL Lite it is not. Manually setting this option to the count of the $postfields array will effectively make it 'true' if there is data to POST. On the other had if the array is empty, it will set it to 0 which is logically a 'false'.


Have comments or feedback on what I wrote? Please share them below!
comments powered by Disqus
Other posts you may like...