Use cURL to call API in PHP - php

I have the following codes, however, it does not return anything-a blank page. But if I plug in the right parameters and place the entire link on web browser, it would return the results I want. I don't want to use file_get_contents because I need to use this function for other API calls that cannot return results by entering the entire link on the address bar. Thanks for helping.
<?php
$data_string ='<HotelListRequest><hotelId>A HOTEL</hotelId></HotelListRequest>';
// Tell CURL the URL of the recipient script
$curl_handle = curl_init ();
curl_setopt ($curl_handle, CURLOPT_URL, 'http://api.ean.com/ean-services/rs/hotel/v3/info?minorRev=4&cid=MYID&apiKey=MYAPIKEY&customerSessionId=&locale=en_US&currencyCode=USD&xml=');
// This section sets various options. See http://www.php.net/manual/en/function.curl-setopt.php
curl_setopt ($curl_handle, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($curl_handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($curl_handle, CURLOPT_POST, true);
curl_setopt ($curl_handle, CURLOPT_POSTFIELDS, $data_string);
// Perform the POST and get the data returned by the server.
$result = curl_exec ($curl_handle);
// Close the CURL handle
curl_close ($curl_handle);
echo $result;
?>

If you put everything into a browser and it works, you're using GET data. Does the service support the use of POST data (which is what you're sending in your example)? Have you tried sending all the data via the CURLOPT_URL?
Also, you'll want to change the data string to
"xml=".$data_string
and possibly you're other arguments as well (depending on the API).

According to http://php.net/manual/en/function.curl-setopt.php :
The full data to post in a HTTP "POST" operation. To post a file,
prepend a filename with # and use the full path. The filetype can be
explicitly specified by following the filename with the type in the
format ';type=mimetype'. This parameter can either be passed as a
urlencoded string like 'para1=val1&para2=val2&...' or as an array with
the field name as key and field data as value. If value is an array,
the Content-Type header will be set to multipart/form-data. As of PHP
5.2.0, value must be an array if files are passed to this option with the # prefix.
So you should modify you $data_string variable content to match the required format.

Related

cURL retrieve only header without doing HEAD

So I am trying to retrieve only headers using cURL with the following:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, true); // we want headers
curl_setopt ($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT,10);
$output = curl_exec($ch);
The problem is that while trying to get headers of large file the script uses all the memory. I would like to avoid getting also the body and I have tried to use:
curl_setopt($ch, CURLOPT_NOBODY, true);
The problem is that this issues a HEAD request instead of GET. And some website retrun an error when you request with HEAD.
Is there any way with curl to retrieve only header without doing HEAD request?
First, don't use CURLOPT_RETURNTRANSFER as that's the option that makes it keep the entire response in memory.
Then, two options:
A) use a write callback and make that abort the transfer as soon as the first byte of the body is returned. There's a write callback example in the PHP.net docs.
B) use CURLOPT_RANGE and ask for only the first byte to be retrieved, 0-0. This avoids the write callback but has the downside that not all HTTP servers and URLs will acknowledge it.
If you dont have to use cURL, you could use get_headers(). By default get_headers uses a GET request to fetch the headers. And you could also modify that request by using stream_context_set_default()
$headers = get_headers('http://example.com');
More Info: PHP: get_headers

SagePay Server URL Encoding accented characters issue

I'm struggling to get my head around the encoding of parameters sent to SagePay via cURL. According to their docs all parameters need to be URL encoded. I'm using PHP's urlencode method on my parameters before passing them as a string to SagePay. Here's an example of part of the string:-
$data = "BillingFirstnames=Jos%C3%A9+Luis&BillingSurname=Test" ...
However, it is failing to correctly render the accented "é" on the SagePay Server website:-
Firstname: José
SagePay's docs state that you can pass accented characters as part of the billing first name (etc.) and that the parameter should be URL encoded.
Our cURL request looks something like this (in case this is of help):-
// Set the URL
curl_setopt($cs, CURLOPT_URL, $url);
// No headers, please
curl_setopt ($cs, CURLOPT_HEADER, 0);
// It's a POST request
curl_setopt ($cs, CURLOPT_POST, 1);
// Set the fields for the POST
curl_setopt ($cs, CURLOPT_POSTFIELDS, $data);
// Return it direct, don't print it out
curl_setopt($cs, CURLOPT_RETURNTRANSFER,1);
// This connection will timeout in 30 seconds
curl_setopt($cs, CURLOPT_TIMEOUT,30);
curl_setopt($cs, CURLOPT_SSL_VERIFYPEER, FALSE);
$response = preg_split('/$\R?^/m',curl_exec($cs));
Any suggestions on how to resolve this so that the first name appears as "José" on SagePay?
You can set utf-8 content type through http header. For example:
curl_setopt($cs, CURLOPT_HTTPHEADER,
array('Content-Type: application/x-www-form-urlencoded;charset="utf-8"')
);
You've already mentioned about the php urlencode in your question, but I didn't see it on your code. So adding that again too.
$post = "age=15&name=".urlencode("José");

Send cUrl data without vars array

I try to post data without setting variable or array. I don't know it's possible ?
When i send $data = array('var_name'=>'var_val') everything works fine, but when i set $data ='to send' i don't get any post data.
$data = 'sample data to send';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
//curl_setopt($ch,CURLOPT_HTTPHEADER,array('Content-type: application/json'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$resp = curl_exec($ch);
From the manual:
CURLOPT_POSTFIELDS
The full data to post in a HTTP "POST" operation. To post a file, prepend a filename with # and use the full path. The filetype can be explicitly specified by following the filename with the type in the format ';type=mimetype'. This parameter can either be passed as a urlencoded string like 'para1=val1&para2=val2&...' or as an array with the field name as key and field data as value. If value is an array, the Content-Type header will be set to multipart/form-data. As of PHP 5.2.0, value must be an array if files are passed to this option with the # prefix.
Simple strings are assumed to be key/value pairs by the other end. Whatever the other end is doesn't see the un-keyed value you're passing. If this was a GET instead of a POST, I'd say just inspect the query string. As that isn't the case, you'll want to send the data with a key and a value instead, or figure out how the other end reads raw POST data. If the other end is PHP, there are at least two ways to do this.
The reason is "to send" becomes a key for $_POST data. To be able to see it, in the PHP file which is $url, do var_dump($_POST); This should show that key value on output. But as you can expect, it doesn't have any value.
You can take the data you have written in POSTFIELDS as raw with
$yourPostedData = file_get_contents('php://input');
POST request does not necessarily contain pairs of variable = value. Sometimes it contains raw data. To access it, you need to use the variable $HTTP_RAW_POST_DATA that will be filled with raw POST data in that case.

How do I re-post the entire $_REQUEST to another endpoint?

I have an application that interacts with an outside API. When the remote serve posts a request containing specific status, I need to re-send the entire contents of that post to a different application through an external URL.
Is it possible to take the entire $_REQUEST and re-post it else where, or do I have to iterate through $_REQUEST and build a new array for posting where I need to?
$_REQUEST is an array. So yes you can post it where you need to. Just use cURL
If I correctly understand your question you're able to do it with CURL:
$ch = curl_init("http://sitename.com/");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, "field1=value1&field2=value2");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
where "field1=value1&field2=value2" is replaced with your args
Also you're able to get result of how operation is completed:
after $result = curl_exec($ch); use:
$result_info = curl_getinfo($ch);
now in $result_info['http_code'] is placed HTTP CODE. If it's 200 then SUCCESS (of course the code might be different in some cases - e.g. when it's artificially configured to another code)
you should distinct between $_POST and $_GET values.
$_REQUEST represents all values that are coming by GET and POST, if one key is set in $_POST and $_GET value from $_POST have precedence when getting saved to the $_REQUEST array.
append everything that comes via $_GET to the URL and send everything from $_POST in the request body.
Using $HTTP_RAW_POST_DATA can save the overhead of reencoding, if both segements are a POST method
Lookup CURL, this should be rather easy:
http://davidwalsh.name/execute-http-post-php-curl
I would use the cURL extension.

use php to parse json data posted from another php file

my web hosting has blocked the outward traffic so i am using a free web hosting to read data and post it to my server but the problem is that my php file receives data in the $_REQUEST variable but is not able to parse it.
post.php
function postCon($pCon){
//echo $pCon;
$ch = curl_init('http://localhost/rss/recv.php');
curl_setopt ($ch, CURLOPT_POST, 1);
curl_setopt ($ch, CURLOPT_POSTFIELDS, "data=$pCon");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$d=curl_exec ($ch);
echo $d."<br />";
curl_close ($ch);
}
recv.php
<?php
if(!json_decode($_REQUEST['data']))
echo "json error";
echo "<pre>";
print_r($data);
echo "</pre>";
?>
every time it gives json error.
but echo $_REQUEST['data'] gives the correct json data.
plz help.
Should not this ?
$posts = array('data'=>$pCon);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $posts);
even the example in doc show that
from doc
The full data to post in a HTTP "POST" operation. To post a file, prepend a filename with # and use the full path. This can either be passed as a urlencoded string like 'para1=val1&para2=val2&...' or as an array with the field name as key and field data as value. If value is an array, the Content-Type header will be set to multipart/form-data. As of PHP 5.2.0, files thats passed to this option with the # prefix must be in array form to work.
your existing way should work too,
is it possible that $pCon contains some urlencoded values such as =, ? ?
$posts = array('data'=>$pCon);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $posts);
this worked.
(the person who answered this question deleted the post so i couldnt catch his name, so thankx)
edit:
there still was a small error every quote (") was changed to (\") i had a very hard time correcting this so now i am not sending data in json directly but first base64 encode it and when the page receives it , it base64 decodes it.
now this workds flawlessly...
thankyou all...

Categories