POST call fails (file_get_contents warning?) - php

I want to make a post call with the following code:
function addWorkout() {
// url for workouts
$url = "https://jawbone.com/nudge/api/v.1.1/users/#me/workouts";
// set data to send
$data = http_build_query(array(
'time_created' => intval($_GET['starttime']),
'time_completed' => intval($_GET['endtime']),
'sub_type' => intval($_GET['sport']),
'calories' => intval($_GET['calories']),
));
var_dump($data);
$options = array(
'http' => array(
"header" => "Content-Type: Authorization: Bearer {$_COOKIE['access_token']}\r\n",
'method' => 'POST',
'content' => $data
),
);
var_dump($options);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
var_dump($result);
}
However it doesn't successfully make the post call. The following message appears:
Warning: file_get_contents(https://...#me/workouts): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in C:\wamp\www\FitnessWebApp\.idea\html\sport.php on line 90
Call Stack
# Time Memory Function Location
1 0.0006 280568 {main}( ) ..\sport.php:0
2 1.2201 293408 addWorkout( ) ..\sport.php:19
3 1.2204 296272 file_get_contents ( ) ..\sport.php:90
var_dump of $data:
string 'time_created=1368652731&time_completed=1368656325&sub_type=1&calories=333' (length=73)
var_dump of $options:
array (size=1)
'http' =>
array (size=3)
'header' => string 'Content-Type: Authorization: Bearer ...
' (length=166)
'method' => string 'POST' (length=4)
'content' => string 'time_created=1368652731&time_completed=1368656325&sub_type=1&calories=333' (length=73)
API documentation shows the following example:
POST https://jawbone.com/nudge/api/v.1.1/users/#me/workouts HTTP/1.1
Host: jawbone.com
time_created=1368652731&time_completed=1368656325&sub_type=3&calories=115

Ok, you want to do a POST request with file_get_contents.
I think the error is in this line:
´"header" => "Content-Type: Authorization: Bearer {$_COOKIE['access_token']}\r\n"
There are two elements here Content-Type and Authorization.
I suggest to alter this into:
$options = array(
'http' => array(
"header" => [
"Authorization: Bearer " . $_COOKIE['access_token'],
"Content-Type: application/x-www-form-urlencoded"],
'method' => 'POST',
'content' => $data
),
);
I don't know if Content-Type is correct, normally API's use "Content-Type: application/json"
Or just leave it away.

file get contents does not work with https. You will have to use curl instead.
/* gets the data from a URL */
function get_data($url) {
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //will not complain about certs
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
then call
$returned_content = get_data('https://jawbone.com/nudge/api/v.1.1/users/#me/workouts');

Related

Getting error file_get_contents failed to open stream when trying to make an API post request without cURL

Please I need your help. I need to make a post request using file get contents and I am getting this error
file_get_contents(https://api.paystack.co/transferrecipient): failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request
Here's the company's cURL requirement:
curl -X POST -H "Authorization: Bearer SECRET_KEY" -H "Content-Type: application/json" -d '{
"type": "nuban",
"name": "Account 1029",
"description": "Customer1029 bank account",
"account_number": "01000000010",
"bank_code": "044",
"currency": "NGN",
}' "https://api.paystack,co/transferrecipient
AND MY CODE
//create the content to post to get recipient code
$content = json_encode([
'type' => 'nuban',
'name' => $request->username,
'description' => $request->username.' bank account',
'account_number' => $request->acc_number,
'bank_code' => $request->bank,
'currency' => 'NGN'
]);
$opt = [
"http" => [
'method' => 'POST',
'header' => 'Content-Type: application/json',
'header' => 'Authorization: Bearer secret_key',
$content
]
];
$con = stream_context_create($opt);
$datas = file_get_contents('https://api.paystack.co/transferrecipient', false, $con);
return $datas = json_decode($datas, true);
You have two header keys and no content key for your json payload. You should be able to change the header to an array and set the content key as follows:
$opt = array(
'http' => array(
'method' => 'POST',
'header' => array(
"Content-Type: application/json",
"Authorization: Bearer secret_key"
),
'content' => $content
)
);
I think this will be easier with php-curl:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"https://api.paystack.co/transferrecipient");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'method' => 'POST',
'header' => 'Content-Type: application/json',
'header' => 'Authorization: Bearer secret_key'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
curl_close ($ch);

PHP stream post request not working, but works with curl

I want to send post request as php stream
$aruguments = http_build_query(
array(
'apikey' => 'xxxxxxxxxxxxxxxxxxxxxxxx',
'appid' => 730,
'min' => 20,
'items_per_page' => 100
)
);
$opts_stream = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-Type: application/json' .
'x-requested-with: XMLHttpRequest',
'content' => $aruguments
)
);
$context_stream = stream_context_create($opts_stream);
$json_stream = file_get_contents('https://api.example.de/Search', false, $context_stream);
$data_stream = json_decode($json_stream, TRUE);
For some reason i get error saying:
failed to open stream: HTTP request failed! HTTP/1.1 403 Forbidden
If i send this same request with cUrl it works normaly but its very slow.
Here is my cUrl request that works
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.example.de/Search');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{ \"apikey\": \"xxxxxxxxxxxxxxxxxxxxxxxxxxxx\",\"min\": 20, \"appid\": 730, \"items_per_page\": $number_of_items_per_request }");
curl_setopt($ch, CURLOPT_POST, 1);
$headers = array();
$headers[] = 'Accept: application/json';
$headers[] = 'Content-Type: application/json';
$headers[] = 'X-Requested-With: XMLHttpRequest';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
curl_close ($ch);
There are a couple of issues with the posted code.
Headers
When you're adding headers, you set them all in one single string. For the target server to know when one header ends and the other begins, you need to separate them using new lines (\r\n):
'header' => "Content-Type: application/json\r\n"
. "x-requested-with: XMLHttpRequest\r\n",
Post data
The big difference between your stream context and your cURL code is that your cURL code are posting the data in json-format, while you're stream context are posting the data as a x-www-form-urlencoded string. You're still telling the server that the content is json though, so I guess the server gets a bit confused.
Post the data as json instead by changing:
$aruguments = http_build_query(
array(
'apikey' => 'xxxxxxxxxxxxxxxxxxxxxxxx',
'appid' => 730,
'min' => 20,
'items_per_page' => 100
)
);
to
$aruguments = json_encode(
array(
'apikey' => 'xxxxxxxxxxxxxxxxxxxxxxxx',
'appid' => 730,
'min' => 20,
'items_per_page' => 100
)
);

synapse PHP API sandbox mode showing error "None is not of type 'string'"

I am working with synapse and having issue while uploading user doc attachment, actually same thing is working on our live server but not working with test server in sandbox mode
If any one can help :)
Reference URL: https://docs.synapsepay.com/v3/docs/attach-document
API URL: https://sandbox.synapsepay.com/api/3/user/doc/attachments/add
Response: Array ( [error] => Array ( [en] => None is not of type 'string' ) [error_code] => 200 [http_code] => 400 [success] => )
Code as Below:
$url = "https://sandbox.synapsepay.com/api/v3/user/doc/attachments/add";
// KYC Documentation
$payload = array(
"login" => array(
//Oauth_key of the user to add KYC doc
"oauth_key" => "hTUCH4kO89qGZDpyEdoq55ODYugwwRsd57ti8ohZ"
),
"user" => array(
//doc data
"doc" => array(
'attachment' => 'data:text/csv;base64,SUQsTmFtZSxUb3RhbCAoaW4gJCksRmVlIChpbiAkKSxOb3RlLFRyYW5zYWN0aW9uIFR5cGUsRGF0ZSxTdGF0dXMNCjUxMTksW0RlbW9dIEJlbHogRW50ZXJwcmlzZXMsLTAuMTAsMC4wMCwsQmFuayBBY2NvdW50LDE0MzMxNjMwNTEsU2V0dGxlZA0KNTExOCxbRGVtb10gQmVseiBFbnRlcnByaXNlcywtMS4wMCwwLjAwLCxCYW5rIEFjY291bnQsMTQzMzE2MjkxOSxTZXR0bGVkDQo1MTE3LFtEZW1vXSBCZWx6IEVudGVycHJpc2VzLC0xLjAwLDAuMDAsLEJhbmsgQWNjb3VudCwxNDMzMTYyODI4LFNldHRsZWQNCjUxMTYsW0RlbW9dIEJlbHogRW50ZXJwcmlzZXMsLTEuMDAsMC4wMCwsQmFuayBBY2NvdW50LDE0MzMxNjI2MzQsU2V0dGxlZA0KNTExNSxbRGVtb10gQmVseiBFbnRlcnByaXNlcywtMS4wMCwwLjAwLCxCYW5rIEFjY291bnQsMTQzMzE2MjQ5OCxTZXR0bGVkDQo0ODk1LFtEZW1vXSBMRURJQyBBY2NvdW50LC03LjAwLDAuMDAsLEJhbmsgQWNjb3VudCwxNDMyMjUwNTYyLFNldHRsZWQNCjQ4MTIsS2FyZW4gUGF1bCwtMC4xMCwwLjAwLCxCYW5rIEFjY291bnQsMTQzMTk5NDAzNixTZXR0bGVkDQo0NzgwLFNhbmthZXQgUGF0aGFrLC0wLjEwLDAuMDAsLEJhbmsgQWNjb3VudCwxNDMxODQ5NDgxLFNldHRsZWQNCjQzMTUsU2Fua2FldCBQYXRoYWssLTAuMTAsMC4wMCwsQmFuayBBY2NvdW50LDE0Mjk3NzU5MzcsU2V0dGxlZA0KNDMxNCxTYW5rYWV0IFBhdGhhaywtMC4xMCwwLjAwLCxCYW5rIEFjY291bnQsMTQyOTc3NTQzNCxTZXR0bGVkDQo0MzEzLFNhbmthZXQgUGF0aGFrLC0wLjEwLDAuMDAsLEJhbmsgQWNjb3VudCwxNDI5Nzc1MzY0LFNldHRsZWQNCjQzMTIsU2Fua2FldCBQYXRoYWssLTAuMTAsMC4wMCwsQmFuayBBY2NvdW50LDE0Mjk3NzUyNTAsU2V0dGxlZA0KNDMxMSxTYW5rYWV0IFBhdGhhaywtMC4xMCwwLjAwLCxCYW5rIEFjY291bnQsMTQyOTc3NTAxMyxTZXR0bGVkDQo0MjM1LFtEZW1vXSBCZWx6IEVudGVycHJpc2VzLC0wLjEwLDAuMDAsLEJhbmsgQWNjb3VudCwxNDI5MzMxODA2LFNldHRsZWQNCjQxMzYsU2Fua2FldCBQYXRoYWssLTAuMTAsMC4wMCwsQmFuayBBY2NvdW50LDE0Mjg4OTA4NjMsU2V0dGxlZA0KNDAzMCxTYW5rYWV0IFBhdGhhaywtMC4xMCwwLjAwLCxCYW5rIEFjY291bnQsMTQyODIxNTM5NixTZXR0bGVkDQo0MDE0LFtEZW1vXSBCZWx6IEVudGVycHJpc2VzLC0wLjEwLDAuMDAsLEJhbmsgQWNjb3VudCwxNDI4MTI1MzgwLENhbmNsZWQNCjM4MzIsU2Fua2FldCBQYXRoYWssLTAuMTAsMC4wMCwsQmFuayBBY2NvdW50LDE0MjcxMDc0NzAsU2V0dGxlZA0KMzgyNixTYW5rYWV0IFBhdGhhaywtMC4xMCwwLjAwLCxCYW5rIEFjY291bnQsMTQyNzAzNTM5MixTZXR0bGVkDQozODI1LFNhbmthZXQgUGF0aGFrLC0wLjEwLDAuMDAsLEJhbmsgQWNjb3VudCwxNDI3MDMyOTM3LFNldHRsZWQNCg=='
),
"fingerprint" => "suasusau21324redakufejfjsf",
)
);
$options = array(
'http' => array(
'method' => 'POST',
'content' => json_encode( $payload ),
'header' => "Content-Type: application/json\r\n" .
"Accept: application/json\r\n"
)
);
$data_string = json_encode($payload);
curlIT($url, $data_string);
function curlIT($url, $fields){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Accept: application/json')
);
$result = curl_exec($ch);
print_r($result);
}
exit;
?>
Synapse api changed you need to send auth key and client id in headers
Take a look of new document
https://docs.synapsepay.com/docs/adding-documents

doing a REST PUT in PHP

I hope my question will be understood, my english is a not so good.
I'm nearly new with PHP and I just discovered REST APIs: I'm trying to use a REST API from my PHP script. Docs for the API can be found here
My final goal is to get a single product from this webservice and update it by adding the wholesalePrices array.
I've already managed to perform a GET request using file_get_contents(), in order to get the product ID i want to update. Now I have such id but can't understand how to perform the PUT request: as far I can understand, there are mainly two ways to do REST calls in PHP: one with file_get_contents, another by using cURL.
Since I used file_get_contents for my GET request, I continued with this approach, but my code:
$wholesalePrices = json_encode($wholesalePrices);
$dataRAW = array(
"wholesalePrices" => $wholesalePrices
);
$dataToPut = http_build_query($dataRAW);
$context = [
'http' => [
'method' => 'PUT',
'header' => "Authorization: apikeystring\r\n" . "Content-Length: " . strlen($dataToPut) . "\r\n" . "Content-Type: application/json\r\n",
'content' => $dataToPut
]
];
$context = stream_context_create($context);
$url = "https://app.ecwid.com/api/v3/xxxxxxx/products/".urlencode($productId)."?token=".urlencode(myToken);
$result = file_get_contents ($url, false, $context);
returns a PHP warning:
Warning: file_get_contents(https://app.ecwid.com/api/v3/xxxxxxxxx/products/xxxxxxxxx?token=xxxxxxxxxxx): failed to open stream: HTTP request failed! HTTP/1.1 400 Wrong JSON format: A JSONObject text must begin with '{' at 1 [character 2 line 1] in upload.php on line 95
var_dumping $wholesalePrices just after the json_encode() results in
string '[{"quantity":1,"price":0},{"quantity":5,"price":6},{"quantity":25,"price":12},{"quantity":100,"price":25}]' (length=106)
where am I wrong?
ok, I tried using RamRaider approach and now my code is this
$data = json_encode(array('wholesalePrices' => $wholesalePrices)/*, JSON_FORCE_OBJECT*/);
$dataRAW = array(
"wholesalePrices" => $wholesalePrices
);
$dataToPut = $dataRAW;
$dataToPut = http_build_query($dataRAW);
$context = array('http' => array('method' => 'PUT',
'header' => "Authorization: apikeystring\r\nContent-Length: ".strlen($data)."\r\nContent-Type: application/json\r\n",
'content' => $data));
$context = stream_context_create($context);
$url = "https://app.ecwid.com/api/v3/".urlencode(MY_STORE_ID)."/products/".urlencode($productId)."?token=".urlencode(MY_TOKEN);
$result = file_get_contents ($url, false, $context);
But I obtain a HTTP request failed! HTTP/1.1 400 Field Product.wholesalePrices should be an array message.
If I comment the , JSON_FORCE_OBJECT instead, the HTTP message becomes 409 Conflict and it refers at the line with $result = file_get_contents ($url, false, $context); so perhaps I am on the right track, but how can I troubleshoot such error?
ok, done some mods: now - after the json_encode() - my dataToPut (which I put in "Content" in the HTTP request) var_dumps as following (WPPair is a class I specifically created to reproduce the format required):
object(stdClass)[3]
public 'wholesalePrices' =>
array (size=3)
1 =>
object(WPpair)[5]
public 'quantity' => int 5
public 'price' => int 6
2 =>
object(WPpair)[4]
public 'quantity' => int 25
public 'price' => int 12
3 =>
object(WPpair)[6]
public 'quantity' => int 100
public 'price' => int 25
so I think it has to be right for the api. But I still get a HTTP request failed! HTTP/1.1 400 Bad Request
Ok, finally I managed to form a (perhaps) right structure for my JSON, all the more so as Postman validates my dataToPut with an HTTP
200 OK
And my test record results updated.
This is the print_r() output on dataToPut after json_encode():
string
'{"id":56782231,"wholesalePrices":[{"quantity":5,"price":5.64},{"quantity":25,"price":5.28},{"quantity":100,"price":4.5}]}'
(length=121)
However, if I try to send the same JSON from my PHP page, I still get a
failed to open stream: HTTP request failed!
and in fact, my records still aren't updated.
Here's my code:
$dataToPut = $dataRAW;
$dataRAW = http_build_query($dataRAW);
$context = [
'http' => [
'method' => 'PUT',
'header' => "Authorization: apikeystring\r\n" . "Content-Length: ".sizeof($dataToPut)."\r\n" . "Content-Type: application/json\r\n",
'content' => $dataToPut
]
];
$context = stream_context_create($context);
$url = "https://app.ecwid.com/api/v3/xxxxxxx/products/".urlencode($productId)."?token=".urlencode(myToken);
$dataToPut = json_encode($dataToPut);
$result = file_get_contents($url, false, $context);
Where am I wrong this time?
After rewriting my code by using cURL instead of file_get_contents to connect to the API, I managed to get it to work.
Now the API call part looks like this:
$dataToPut = $dataRAW;
$dataRAW = http_build_query($dataRAW);
$context = [
'http' => [
'method' => 'PUT',
'header' => "Authorization: apikeystring\r\n" . "Content-Length: ".sizeof($dataToPut)."\r\n" . "Content-Type: application/json\r\n",
'content' => $dataToPut
]
];
$context = stream_context_create($context);
$url = "https://app.ecwid.com/api/v3/xxxxxxx/products/".urlencode($productId)."?token=".urlencode($myToken);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Host: app.ecwid.com','Content-Type: application/json;charset=utf-8','Cache-Control: no-cache'));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $dataToPut);
// Make the REST call, returning the result
$response = curl_exec($curl);
echo ($response."<br/>");
if (!$response) {
echo("Connection Failure: ".curl_error($curl));
die();
}
curl_close($curl);
Without seeing the documentation for their api I might be leading you astray but the error message does suggest that their api expects json data whereas you encode the data and then add to an array which seems back to front somehow.
$data = json_encode( array( 'wholesalePrices' => $wholesalePrices ), JSON_FORCE_OBJECT );
/* Perhaps this also is not required */
#$data = http_build_query( $data );
$context = array(
'http' => array(
'method' => 'PUT',
'header' => "Authorization: apikeystring\r\nContent-Length: " . strlen( $data ) . "\r\nContent-Type: application/json\r\n",
'content' => $data
)
);
$context = stream_context_create( $context );
$url = "https://app.ecwid.com/api/v3/7560546/products/".urlencode( $productId )."?token=".urlencode( myToken );
$result = file_get_contents( $url, false, $context );
Having had a quick look at the api documentation I found the following:
PUT https://app.ecwid.com/api/v3/{storeId}/products/{productId}?token={token}
Request body
A JSON object of type 'Product’ with the following fields:
wholesalePrices -> Array<WholesalePrice>
described as: "Sorted array of wholesale price tiers (quantity limit and price pairs)"
The given example request to update a product is:
PUT /api/v3/4870020/products/39766764?token=123456789abcd HTTP/1.1
Host: app.ecwid.com
Content-Type: application/json;charset=utf-8
Cache-Control: no-cache
{
"compareToPrice": 24.99,
"categoryIds": [
9691094
]
}
So using test data
$wholesalePrices=array(
array('quantity'=>10,'price'=>1000),
array('quantity'=>2,'price'=>43),
array('quantity'=>43,'price'=>34),
array('quantity'=>7,'price'=>5),
array('quantity'=>9,'price'=>63),
);
$data = json_encode( array( 'wholesalePrices' => $wholesalePrices ) );
echo '<pre>',$data,'</pre>';
Gives data in the format:
{
"wholesalePrices":[
{"quantity":10,"price":1000},
{"quantity":2,"price":43},
{"quantity":43,"price":34},
{"quantity":7,"price":5},
{"quantity":9,"price":63}
]
}

file_get_contents not working for fetching data from facebook using batch requests

file_get_contents not working for fetching fata from facebook using batch requests.Am using the code below:
$url='https://graph.facebook.com/?batch=[{ "method": "POST", "relative_url":"method/fql.query?query=SELECT+first_name+from+user+where+uid=12345678"}]& access_token=xxxxxxx&method=post';
echo $post = file_get_contents($url,true);
it produces
Warning: file_get_contents(graph.facebook.com/?batch=[{ "method": "POST", "relative_url": "method/fql.query?query=SELECT+first_name+from+user+where+uid=12345"}]&access_to‌ ​ken=xxxx&method=post): failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request in /home/user/workspace/fslo/test.php on line 9
I would say the most likely answer to this is that you need to pass the URL values through urlencode() - particularly the JSON string.
Also, you should be POSTing the data.
Try this code:
NB: I presume you are building the URL from several variables. If you edit the question with your actual code, I will provide a solution using that code
<?php
$baseURL = 'https://graph.facebook.com/';
$requestFields = array (
'batch' => '[{"method":"POST","relative_url":"method/fql.query?query=SELECT+first_name+from+user+where+uid=12345678"}]',
'access_to‌ken' => 'whatever'
);
$requestBody = http_build_query($requestFields);
$opts = array(
'http'=>array(
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n"
. "Content-Length: ".strlen($requestBody)."\r\n"
. "Connection: close\r\n",
'content' => $requestBody
)
);
$context = stream_context_create($opts);
$result = file_get_contents($baseURL, FALSE, $context);
A "more standard" way to do this these days is with cURL:
<?php
$baseURL = 'https://graph.facebook.com/';
$requestFields = array (
'batch' => '[{"method":"POST","relative_url":"method/fql.query?query=SELECT+first_name+from+user+where+uid=12345678"}]',
'access_to‌ken' => 'whatever'
);
$requestBody = http_build_query($requestFields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $baseURL);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/x-www-form-urlencoded',
'Content-Length: '.strlen($requestBody),
'Connection: close'
));
$post = curl_exec($ch);

Categories