Adding an option to a PHP Curl resource - php

The instructions I have for using an api gives two options.
One requires a zipCode input and one does not.
Using PHP I have successfully built a curl resource using curl_setop for the case that uses the zipCode but not the case that omits the zipCode. The case without the zipCode is supposed to have an extra option after the URL.
All I have been given for instructions is that the curl should be like:
curl -i -X POST -H "Content-Type:application/json" -H "authToken:12345" https://connect.apisite.com/api/v1/users -d'
[{
"firstName": "John",
"lastName": "Smith",
"emailAddress": {
"address": "johnsmith#test.com"
}
}]'
for the case without the zipCode
and with the zipCode
curl -i -X POST -H "Content-Type:application/json" -H
"authToken:12345" https://connect.apisite.com/api/v1/users '
[{
"firstName": "John",
"lastName": "Smith",
"emailAddress": { "address": "johnsmith#test.com" },
"homeAddress" : { "postalCode" : "48124" }
}
}]'
My problem is that I do not know how to add the -d to the curl resource that appears in the first case just after the URL
This works for me:
$url = "https://connect.apisite.com/api/v1/users";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
$request_headers = array();
$request_headers[] = 'authToken: ' . $authResponse;
$request_headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
$response = curl_exec($ch);
I tried just appending the -d to the URL as
$url = "https://connect.apisite.com/api/v1/users -d";
That did not work.
My guess is there is a constant I need to use like
curl_setop($ch, CURLOPT_XXXXX, '-d');
but I do not know what CURLOPT_XXXX should be.
Any help would be appreciated.

I'm not sure why you use curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); as your call structure seems could be done by a regular POST call which could be handled by:
curl_setopt(CURLOPT_POST, true);
which in turn will call the -d flag of cURL as per PHP document:
CURLOPT_POST: TRUE to do a regular HTTP POST. This POST is the normal application/x-www-form-urlencoded kind, most commonly used by HTML forms.
Also, you need to change curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); because doing this will make cURL to pass the data as multipart/form-data. Instead, structure your data as a URL-encoded string, something like
curl_setopt($ch, CURLOPT_POSTFIELDS, urlencode(json_encode($postData)));
(note: I haven't tested the latter line above but you can test it and adjust as per your requirements), as per PHP documentation note:
Note:
Passing an array to CURLOPT_POSTFIELDS will encode the data as multipart/form-data, while passing a URL-encoded string will encode the data as application/x-www-form-urlencoded.

Thanks everyone for your help and suggestions.
As was mentioned I did not need to do anything to add the -d
I got the response I need using the following for postData
$postData = json_encode(array(array('emailAddress' => $emailObj, 'firstName' => $firstName, 'lastName' => $lastName)));
or
$postData = json_encode(array(array('emailAddress' => $emailObj, 'firstName' => $firstName, 'lastName' => $lastName, 'homePostalAddress' => $homePostalObj)));

In both request the method is POST, as the previous answer you can set CURLOPT_POST option. I see the only different is about the data you are sending, in one without zipCode and another with. So, you can just prepare the data before including the zipCode or not in your array of data. You can try something like below.
$dataRequest = [
'firstName' => "John",
'lastName' => "Smith",
'emailAddress' => [
'address' => 'johnsmith#test.com'
],
'homeAddress' => [ //dont send this key in the case you dont want zipCode in the request.
'postalCode'=> '48124'
],
];
$url = "https://connect.apisite.com/api/v1/users";
$authToken = '12345';
$ch = curl_init();
/**
the idea with urldecode is because some api does not accept the
encoded urls in your case is not important due your data does not
contains any url but if tomorrow you want to include smth like
'customerUrl'=>'https://myhomepage.com' the result of http_build_query
will be like 'https%3A%2F%2Fmyhomepage.com'
*/
$data = urldecode(http_build_query($dataRequest));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, "{$authToken}:");
$headers = [];
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
if (!curl_errno($ch)) {
/**
HANDLE RESPONSE, CHECK FOR PROPER HTTP CODE DEPENDING OF THE API RESPONSE,
IN YOUR CASE I GUESS IS CREATE USER YOUR GOAL, SO MAYBE RESPONSE IS 'HTTP_CREATED'
BUT IF THIS FUNCTION WILL BE GENERIC BETTER SWITCH LIKE THIS:
switch ($http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE)) {
case Response::HTTP_OK:
case Response::HTTP_CREATED:
case Response::HTTP_ACCEPTED:
$response = json_decode($response, true);
break;
default:
$response = [];
}
*/
}
curl_close($ch);
return $response;
This example is with content-type not in json format, you can change it if is requirement of api.

Related

PHP cURL with CURLOPT_POSTFIELDS in json format

I'm not quite familiar with cURL and been struggling on this issue though.
I'm sending a post request by using cURL and the data field is in json format.
My coding:
$ch = curl_init($url);
$authorization = "Authorization: Bearer ".$token;
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json' , $authorization ));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = "test";
$data = <<<DATA
{
"shop_id": 1231232,
"message": "test"
}
DATA;
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
What I'm trying to achieve here is to replace the "message" value with php variable $response. What is the correct way to do that? Thank you!
This has nothing to do with cURL specifically, it's about including variables in a data structure or string.
My first piece of advice would be: don't generate JSON string literals in your code, it's fiddly and potentially error-prone. Build a suitable PHP data structure and then use json_encode() to reliably turn it into a valid JSON string.
As it happens, following this approach also makes your current requirement very easy to achieve using basic PHP:
$data = [
"shop_id" => 1231232,
"message" => $response
];
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
P.S. In a different scenario (e.g. not trying to generate JSON) where using heredoc would be more appropriate, the solution is also simple, you just replace the hard-coded value with the variable:
$data = <<<DATA
{
"shop_id": 1231232,
"message": $response
}
DATA;

Invalid value passed for JSONString Zoho inventory api

I am trying to use the zoho inventory api and converting thier sample curl code for use in php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"https://inventory.zoho.com/api/v1/salesorders");
$vars = array(
"authtoken" => "",
"organization_id" => "",
"JSONString" => '{
"customer_id": 4815000000044080,
}'
);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$vars); //Post Fields
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$headers = [
'Authorization: Zoho-authtoken ',
'Content-Type: application/json;charset=UTF-8',
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$server_output = curl_exec ($ch);
echo $server_output;
curl_close ($ch);
On the page I get this response
{"code":4,"message":"Invalid value passed for JSONString"}
The original code from the docs is
$ curl https://inventory.zoho.com/api/v1/salesorders?authtoken=ba4604e8e433g9c892e360d53463oec5&organization_id=10234695
-X POST
-H "Authorization: Zoho-authtoken ba4604e8e433g9c892e360d53463oec5"
-H "Content-Type: application/json;charset=UTF-8"
-d JSONString='{
"customer_id": 4815000000044080,
}'
I have tried various google searches and it seems that a lot of people have had this same issue and there is no answer given for it yet.
I believe I am trying to add the JSONString in the wrong way
What is the correct way to send the JSONString in php using curl?
Following is the C# code that will not give the following error:
"{"code":4,"message":"Invalid value passed for JSONString"}"` error.
I use a servise http://httpbin.org/post to look, how my post query looks for zoho.
and find an error with symbols \ufeff before JSONString, this is BOM encoding.
So, i change encoding and all right.
Look Example

Make HTTP request in cURL in proper way

I am passing data in Curl as below, it seems I have done something wrong as it is not working.... please guide me how to make the request correctly.
Below is the full code:
<?php
$url = 'https://staging.logistics.com/v2/shipments/create';
$data = '
"request_id" : "10",
"value": "false"
';
$data_string = json_encode(array(
"customer" => $data
));
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type:application/json'
));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Authorization: Basic ZcnM6ZHV55tbXlLZXk="
);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
echo "$result";
?>
I got this HTTP error:
415 Problem accessing /v2/shipments/create. Reason: Unsupported Media
Type
The "Unsupported Media Type" error is because you are not sending valid JSON. Since you create $data as a string, and then json_encode() it, you end up with double-encoded data, which the server does not recognise. The code shown in the question will cause $data_string to be output as
{"customer":"\r\n\"request_id\" : \"10\",\r\n \"value\": \"false\"\r\n"}
A usable version of this would be
{"customer": { "request_id" : "10", "value": "false" } }
To get that, you'd write the code by making a PHP object / array, and then encoding that object:
$data = array("request_id" => "10", "value" => "false");
$data_string = json_encode(array(
"customer" => $data
));
Here's a demo showing the output of the code above.
You could also shorten that code to:
$data = array(
"customer" => array(
"request_id" => "10",
"value" => "false")
)
);
$data_string = json_encode($data);
Your mistake was to confuse the creation of the data in the PHP code with the encoding of it into the textual transmission format (JSON, in this case). Instead you need to create the data in PHP using a (nested) associative arrays and regular arrays in such a way that when you pass that to json_encode(), the output payload is in the correct format required by the API.
Try concatenating the token to the curl option like so
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: ' . $your_token));

URL encoding JSON strings when calling Facebook MarketingAPI

When calling an API endpoint in PHP, what is the difference between passing as a parameter in the URL using
$str = '{\'since\':\'2015-01-01\',\'until\':\'2015-01-22\'}';
'blahblah?access_token=xxx&time_range=' . $str;
versus
$str = '{\'since\':\'2015-01-01\',\'until\':\'2015-01-22\'}';
'blahblah?access_token=xxx&time_range=' . urlencode($str);
Apart from the latter making more likely the URL becoming 'too long'? Knowing that no one is going to see the URL, I just want to retrieve data from the API and output to CSV
Many thanks
via something like this:
$data = array("name" => "Hagrid", "age" => "36");
$data_string = json_encode($data);
$ch = curl_init('http://api.local/rest/users');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);
instead of passing this information in the url via a GET request?
Edit: Actually, can someone just tell me where I can read up on curl command line flags like -G, or how to implement the below in PHP? Thanks
curl -G \
-d "fields=['impressions','campaign_group_name','cost_per_action_type']" \
-d "action_breakdowns=['action_type','action_carousel_card_name']" \
-d "level=adgroup" \
-d "access_token=<ACCESS_TOKEN>" \
"https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/insights"

How to make a JSON Curl request to an api url, getting null

This should be simple I think but I just can't fathom it.
I need to make a request to a url in the following format:
http://ratings.api.co.uk/business/{lang}/{fhrsid}/{format} where lang will be set to en-GB the fhrsid is an identifier and format is json.
I tried the following but I am just getting null in return:
$data = array("lang" => "en-GB", "fhrsid" => "80928");
$data_string = json_encode($data);
$ch = curl_init('http://ratings.api.co.uk/business/json');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string)) );
$Jsonresult = curl_exec($ch);
curl_close($ch);
var_dump(json_decode($Jsonresult));
Any help gratefully received
You are currently posting the data to the URL, while you say you want to put the data in the URL itself.
I.e. now you submit {"lang:"en-GB","fhrsid":80928} to the URL http://ratings.api.co.uk/business/json, but instead you want to retrieve the URL http://ratings.api.co.uk/business/en-GB/80928/json.
Don't use POST as request type, don't specify postfields, don't specify content-length, and do put the data in your URL.
Sending data as arguments is different than sending it within the URL.
If you require a url format of http://ratings.api.co.uk/{lang}/{fhrsid}/{format}, then you must make your curl_init string match that format.

Categories