UPDATED T开发者_StackOverflow社区HANKS 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.
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 :)
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.
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.
Add this line:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
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);
精彩评论