3

UPDATED THANKS TO ANSWERS:

Can someone point out the difference between:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_root);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, "xml"); // tried http_build_query also
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Added this, still no good
return curl_exec($ch);  // returns false

and:

$curl = "curl -X POST -d 'xml' {$api_root}";
return `$curl`;  // returns expected xml from server

AND/OR

More generally, are there any good breakdowns out there for conversion/reference between php's libcurl default values/headers and those of curl on the command line?

I know this is almost a dupe of curl CLI to curl PHP and CLI CURL -> PHP CURL but I'm hoping for something more definitive.

6
  • What is $api_root set to? If curl_exec is returning false then you have a problem with the setup of the object. Commented Jul 22, 2011 at 21:18
  • That's exactly the point. The libcurl is different in some way from the same CLI command - what are the default differences between them? Commented Jul 22, 2011 at 21:22
  • The only real difference is that the libcurl version uses curl_setopt() to specify options, whereas the command line uses arguments. See my updated answer: what is the error code that curl is returning? Commented Jul 22, 2011 at 21:25
  • I agree in general - but there are some defaults that are different between them. That's what I'm looking for, since in theory the options are the same. Commented Jul 22, 2011 at 21:30
  • I don't think it's that there are differences in defaults, I think it's more a matter of the shell environment being slightly different than the PHP environment. I assume that curl_error() clued you in to an SSL issue? Commented Jul 22, 2011 at 22:13

5 Answers 5

4

When you use backticks then PHP invokes a shell. This can be dangerous, especially when you include variables in the command. If someone has a way to influence the value of $api_root they would be able to invoke any command on your system.

Using the API is much safer and probably faster as well as the curl libraries are loaded into PHP.

As for why it's not working it seems others have answered that question :)

Sign up to request clarification or add additional context in comments.

1 Comment

Yeah I'm trying to get the libcurl method working for just that reason. Thanks!
3

curl_exec returns true or false by default. You need to specify CURLOPT_RETURNTRANSFER:

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

Since curl_exec is returning false (not NULL as indicated in the original question), try using curl_error() to determine why it's returning false.

TFM (read it): curl_exec(), curl_setopt()

Edit for posterity's sake:

The OP discovered that an SSL issue was the hindrance. The both libcurl (as called through PHP) and the curl command-line do SSL peer verification for every transaction, unless the user explicitly disables it.

The likely scenario is that the shell environment is using a different CA bundle than PHP's libcurl implementation. To remedy this, set CURLOPT_CAINFO to be the same as the shell's CURL_CA_BUNDLE environment variable and then peer verification should work.

@OP: I'd be curious to know if the above suggestion is confirmed working in your case, or if there is something else different with the SSL configuration.

1 Comment

Yeah sorry about that - === ftw
2

in your php example you are missing
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

from php manual: curl_exec Returns TRUE on success or FALSE on failure. However, if the CURLOPT_RETURNTRANSFER option is set, it will return the result on success, FALSE on failure.

1 Comment

looks like this was first by a few seconds.
2

Add this line:

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

Comments

0

To match the CLI version:

$curl = "curl -X POST -d 'xml' {$api_root}";
return `$curl`;  // returns expected xml from server

I also needed:

// Thanks to all the answers
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 

// This appears to default false on CLI, true in libcurl
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

3 Comments

It's not that it defaults to false on the CLI (peer verification is bypassed only with the -k switch). More likely is that your environment has additional CA certs that aren't included by default in PHP's cURL implementation. You can set CURLOPT_CAINFO to be the same as your shell's CURL_CA_BUNDLE environment variable and then peer verification should work.
Hey mod your answer to include that and it's a green check for you!
See edit; I'm really interested to know if CURLOPT_CAINFO works for you, or if your situation requires disabling peer verification (which can be a bit dangerous).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.