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.
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);
Related
I'm trying to post to a file service with CDN translating the cli -T option to PHP code, but I don't really know what the equivalent is, or what is the corresponding code that would replicate it. I've seen a options around CURLOPT_HTTPHEADER, but that doesn't seem to work in correspondence to other headers.
The exact thing I'm trying to replicate is this:
curl -XPUT -T "test.png" -v -H "X-Auth-Token:MYTOKEN" -H"Content-Type: text/plain" "https://somecdn.com"
I think it's something like this, but I'm unsure:
$ch = curl_init();
// Set up the options
curl_setopt($ch, CURLOPT_URL, "https://mycdn.com/test.txt");
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"X-Auth-Token: mytoken",
"Content-type: text/plain"
)
);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, array("file" => "#test.txt") );
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
I'm surprised, I suppose, that -T flag doesn't have a similar curl_setopt.
So the precise question is this:
What is the proper way to replicate cURL CLI -T "test.png" in PHP?
Take into consideration as PHP 5.5 uploading file this way (#filename) is deprecated.
Also, PHP 5.5 introduces a new option/flag regarding upload process, called by CURLOPT_SAFE_UPLOAD:
TRUE to disable support for the # prefix for uploading files in
CURLOPT_POSTFIELDS, which means that values starting with # can be
safely passed as fields. CURLFile may be used for uploads instead.
Added in PHP 5.5.0 with FALSE as the default value. PHP 5.6.0 changes
the default value to TRUE.
So if you've PHP 5.5+ you must set CURLOPT_SAFE_UPLOAD (though 5.5 is false by default) to false:
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
Another option is using the CURLFile class.
And remember: Filename MUST be absolute path.
In curl PHP script, we add the headers by the curl_setopt CURLOPT_HTTPHEADER option. It works fine with HTTP request like search.yahoo.com but I tried it with the HTTPS request it doesn't work.
I have disable SSL peer verification by setting CURLOPT_SSL_VERIFYPEER option to false. Is there way to implement it?
here is a quick solution
add curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); before curl_exec()
here $ch curl_init() object;
Do refer here for alternative solution
first of all you need to download the CA certificate with your browser and save it as X.509. This will make you able to accept all certificates issued by the CA. Then use the following CURL options:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, "path_to_CA_certificate.crt");
CURLOPT_VERIFYHOST has different options, you can try 0 first in order to aviod CN check, and if it works then try with 2.
Hope it helps.
I'm having some trouble with a particular cURL command and I'd like to see the headers and responses. In the command line I use -v and it displays everything, however...
In PHP I'm attempting to use:
curl_setopt($curl, CURLOPT_VERBOSE, 1);
However, nothing is being displayed.
I'm using PHP 5.3.24 on Windows Server 2008 on IIS.
Supposedly the info is sent into the stderr stream which I assume means the regular log used for PHP errors - however nothing is going there either. I'm getting no header results for cURL commands that I know are working and those that I know are not working.
My guess is that you need to also return the buffer. This code works under Linux and might work for you under Win2008:
$browser = curl_init();
curl_setopt($browser, CURLOPT_URL, $url);
curl_setopt($browser, CURLOPT_RETURNTRANSFER, true);
curl_setopt($browser, CURLOPT_VERBOSE, true);
$data = curl_exec($browser);
echo $data;
I am trying to make a sort of license checking script, but as not all hosts allow curl_exec, I would like to know, if there is any alternative way of making a call-back?
This is how I do it with curl:
curl_setopt($ch, CURLOPT_URL, $url."/my_script.php");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $info);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_exec($ch);
You can simply use file_get_contents() with URLs:
file_get_contents('http://www.google.com');
This may be disabled, though, with just a simple INI option allow_url_fopen.
Alternatively, you may use fsockopen(), which should be available on most systems.
With fsockopen() you can open a socket to a HTTP server, then communicate using standard fwrite() and fread(). The downside is that you must write HTTP request headers by yourself, and you must also parse HTTP response headers too. If you look at fsockopen() on PHP's manual, you can see plenty of examples: http://fr2.php.net/fsockopen
My suggestion is to use cURL as primary option, file_get_contents() as secondary (if ini_get('allow_url_fopen') returns a positive result) and implement solutions likefsockopen() as fallback.
You could switch curl_multi_exec, but that's probably disabled as well.
Alternatively, use the HTTP stream wrapper. To configure a POST request, you'll need to set up your own HTTP context.
When using the PHP curl functions, is there anyway to see the exact raw headers that curl is sending to the server?
You can use curl_getinfo:
Before the call
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
After
$headers = curl_getinfo($ch, CURLINFO_HEADER_OUT);
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_exec($ch);
var_dump(curl_getinfo($ch,CURLINFO_HEADER_OUT));
?>
Only available in php 5.1.3
http://php.net/manual/en/function.curl-getinfo.php
You can verify that they are the same by using your console and hitting
curl http://example.com/ -I
or
curl --trace-ascii /file.txt http://example.com/
AFAIK, the PHP/CURL binding still lacks proper support for CURLOPT_DEBUGFUNCTION which is a callback from libcurl that can provide all those details.
That's the primary reason why I recommend people to work out HTTP scripting things with the curl command line tool and its --trace-ascii option FIRST, then translate that into a PHP function.
be sure to set the CURLINFO_HEADER_OUT option before making the curl_getinfo call
curl_setopt($c, CURLINFO_HEADER_OUT, true);