Troubles "porting" cURL from bash to PHP - php

I'm trying to port this command to PHP:
curl -i -X POST http://website.com \
-H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" \
-H "Accept: Application/json" \
-H "X-Requested-With: XMLHttpRequest" --data "var1=output1&var2=output2"
From bash it works.. I get this JSON output.
This is what I wrote in PHP to try to get the same result:
<?php
function blabla() {
$curl_parameters = array(
'var1' => "output1",
'var2' => "output2",
);
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,"http://website.com");
curl_setopt($ch,CURLOPT_POST,true);
curl_setopt($ch,CURLOPT_HEADER,true);
curl_setopt($ch,CURLOPT_POSTFIELDS,http_build_query( $curl_parameters ));
curl_setopt($ch,CURLOPT_HTTPHEADER,array (
"Content-Type" => "application/x-www-form-urlencoded; charset=UTF-8",
"Accept" => "Application/json",
"X-Requested-With" => "XMLHttpRequest",
));
$output=curl_exec($ch);
curl_close($ch);
}
echo blabla();
?>
Unfortunately with this snippet I just get a 302 Found HTTP header as output (this).. seems like the variables are not passed (the --data part from the bash command).

The problem is with your CURLOPT_HTTPHEADER. It should be an array of strings like this:
curl_setopt($ch,CURLOPT_HTTPHEADER,array(
'Content-Type: application/x-www-form-urlencoded; charset=UTF-8',
'Accept: application/json',
'X-Requested-With: XMLHttpRequest',
));

How about just curl_setopt($ch,CURLOPT_POSTFIELDS, $curl_parameters);? I don't think you need to call http_build_query.

Try add curl follow 302 redirect
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
Also make sure your http_build_query() function uses "&" as argument separator. On some PHP configurations it may be "& amp;" by default
$query = http_build_query($data, '', '&');

Related

application/x-www-form-urlencoded content type hacks curl response in php [duplicate]

This question already has answers here:
Save cURL Display Output String in Variable PHP
(2 answers)
cURL code in PHP dumps output to the page
(2 answers)
cURL and PHP: Stop output to screen
(1 answer)
Closed 3 years ago.
It seems that Content-Type: application/x-www-form-urlencoded just hacked my curl result
I have a curl request below
curl -k -X POST \
--header "Content-Type: application/x-www-form-urlencoded" \
--header "Accept: application/json" \
--data-urlencode "grant_type=naco:pdata:params" \
--data-urlencode "apikey=<apikey>" \
"https://api_endpoint"
Here is how I successful post data and get response as expected.
Here is the succesful result
{
"product_id": "101",
"product_name": "Television"
}
Now when I echoed or var_dump the result ($res) as per code below then $res is empty and as such,
product_name and product_id cannot be printed and yet am having my result response on the page displayed.
I now discovered that it was the Content-Type: application/x-www-form-urlencoded that forces the result to be displayed via
header but cannot allow $res response to echo the result.
Please how do Print product_id and product_name
$header= array(
'Content-Type: application/x-www-form-urlencoded',
"Accept: application/json");
$builder= http_build_query([
'grant_type'=>"naco:pdata:params",
'apikey'=>"xxxxxxx"]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api_endpoint");
curl_setopt($ch, CURLOPT_POSTFIELDS, $builder);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST,'POST');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,false);
$res = curl_exec($ch);
curl_close($ch);
//code below shows empty result and yet i can still see the result response on the page
echo $res
var_dump($res);
$json = json_decode($res, true);
echo $product_name = $json['product_name'];
echo $product_id = $json['product_id'];

I can't retrieve the intent from my wit.ai call

I am starting to use Wit.ai to enhance a small bot I made. I am able to make a request to the wit.ai by doing:
function sendToWitAI($query){
$witRoot = "https://api.wit.ai/message?";
$witVersion = "20170822";
$witURL = $witRoot . "v=" . $witVersion . "&q=" . $query;
$ch = curl_init();
$header = array();
$header[] = "Authorization: Bearer xxxxxxxx";
curl_setopt($ch, CURLOPT_URL, $witURL);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec ($ch);
curl_close ($ch);
return $server_output;
}
However, when receiving the output I just get the same message I sent. For example, if the user types "I want to make a reservation" my $server_output is now "I want to make a reservation" after all that chunk of code above.
Still, I know it reaches wit successfully because I can see it in the logs there and I know the bot says (from wit.ai):
{
"confidence": null
"action": null
"type": "action"
}
On top of this, if I just do a curl with the same query:
curl -XPOST 'https://api.wit.ai/converse?v=20170822&session_id=123abc&q=I%20want%20to%20make%20a%20reservation' \
> -H "Content-Type: application/json" \
> -H "Accept: application/json" \
> -H 'Authorization: Bearer xxxxxxxx'
I get the following output:
{
"confidence" : null,
"type" : "action",
"action" : null,
"entities" : {
"contact" : [ {
"suggested" : true,
"value" : "reservation",
"type" : "value",
"confidence" : 0.95062723294726
} ],
"intent" : [ {
"confidence" : 0.98638622681962,
"value" : "make_reservation"
} ]
}
}
I'm not sure where my error is or what I'm missing to properly handle use of the value like I need.
I've been googling non-stop but I can't find anything after they (wit.ai) deprecated "stories" and there's seldom anything about handling the response.
You're using 2 different end points: /message and /converse.
The log you pasted is from /converse so I'm not even sure your first call went through. Can you try a curl to /message like this
curl -XGET 'https://api.wit.ai/message?v=20170307&q=I%20want%20to%20make%20a%20reservation' \
-H 'Authorization: Bearer $TOKEN'

Need assistance with PHP curl call

Hello: I am trying to do an API call using curl_init; have made some good progress but seem to be stuck...
we have an interface (swagger) that allows us to do the curl call and test it which works: here is the curl commands from that:
curl -X POST --header "Content-Type: application/x-www-form-urlencoded"
--header "Accept: application/json"
--header "Authorization: Bearer xxxxx-xxxxxx- xxxxx-xxxxxxx"
-d "username=xxxxxxxx39%40gmail.com&password=xxxx1234" "http://xxxxxxxxx-xx-xx-201-115.compute-1.amazonaws.com:xxxx/api/users"
here is my attempt to do the same call in PHP code:
$json = '{
"username": "xmanxxxxxx%40gmail.com",
"password": "xxxx1234"
}';
$gtoken='xxxxxx-xxxxxx-xxx-xxxxxxxx';
$token_string="Authorization: Bearer ".$gtoken;
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'http://exx-ccc-vvv-vvvv.compute-1.amazonaws.com:xxxx/api/users', //URL to the API
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $json,
CURLOPT_HEADER => true, // Instead of the "-i" flag
CURLOPT_HTTPHEADER => array('Content-Type: application/x-www-form-urlencoded','Accept: application/json',$token_string)
));
curl_setopt($curl,CURLOPT_RETURNTRANSFER,TRUE);
$resp = curl_exec($curl);
curl_close($curl);
I am getting a response code "500" which makes me think that there is something wrong with my input. So I am wondering if anyone can help with this...
In your command line code, you post a standard URL encoded data string using -d "username=xxxxxxxx39%40gmail.com&password=xxxx1234" but in PHP you are creating a JSON string and sending it as a single post field (not properly URL encoded).
I think this is what you need:
$data = array(
'username' => 'xmanxxxxxx#gmail.com',
'password' => 'xxxx1234',
);
$data = http_build_query($data); // convert array to urlencoded string
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
As far as I can tell the rest of the code looks fine.
Also, you don't explicitly need to set the Content-Type header, cURL will do this for you when you pass a string to CURLOPT_POSTFIELDS. It will set it to multipart/form-data if you pass an array to CURLOPT_POSTFIELDS. But having it doesn't hurt anything either.

curl_exec for uploading files in box api using php fails

I am able to upload the file using curl on the terminal with the following:
curl https://upload.box.com/api/2.0/files/content \
> -H "Authorization: Bearer {access-code}" -X POST \
> -F attributes='{"name":"tested.png", "parent":{"id":"3804480350"}}' \
> -F file=#/Applications/MAMP/htdocs/BoxappTest/test.png
But when I try to do the same using PHP with the following code:
$filePath=realPath("./test.png");
$xmlfile = file_get_contents("codes.xml");
$codes_data = simplexml_load_string($xmlfile);
$access_token=$codes_data->access_code;
$destination_filename="tested.png";
$id="3804480350";
$ch= curl_init();
curl_reset($ch);
echo "Uploading file...",'<br>';
$post = '{"name":"'.$destination_filename.'", "parent":{"id":"'.$id.'"}}';
$postfields = Array("attributes"=>$post,"file" => "#".$filePath);
$headers= Array("Authorization: Bearer " . $access_token);
curl_setopt($ch, CURLOPT_URL, "https://upload.box.com/api/2.0/files/content");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
$output=curl_exec($ch);
$info=curl_getinfo($ch);
curl_close($ch);
if(curl_errno($ch)) {
echo 'Curl error: ' . curl_error($ch);
}
foreach($info as $data => $part) {
echo $data."=".$part, '<br>';
}
echo "File uploaded...",'<br>';
var_dump($output);
It gives me the following output:
Uploading file...
content_type=text/html;charset=UTF-8
http_code=400
header_size=243
request_size=260
filetime=-1
ssl_verify_result=0
redirect_count=0
total_time=1.118914
namelookup_time=0.000738
connect_time=0.022878
pretransfer_time=0.100239
size_upload=335
size_download=0
speed_download=0
speed_upload=299
download_content_length=0
upload_content_length=335
starttransfer_time=1.10153
redirect_time=0
redirect_url=
primary_ip=74.112.185.182
certinfo=Array
primary_port=443
local_ip=10.0.0.188
local_port=50008
request_header=POST /api/2.0/files/content HTTP/1.1 Host: upload.box.com Accept: */* Authorization: Bearer {access-code} Content-Length: 335 Expect: 100-continue Content-Type: multipart/form-data; boundary=------------------------....
File uploaded...
string(0) ""
I have gone over various sites but none of them seem to be right for my problem. No matter what I do, the content_type stays 'text/html'. I have tried to set it in the header and the post fields. But both didn't work. I know I am getting the access codes properly and that they are valid. I am not sure about the curl options though. Setting CURLOPT_VERBOSE or checking for errors does not return anything either. While without the CURLOPT_RETURNTRANSFER option, curl_exec returns true. Can someone help me understand where I am making a mistake here?
I was not able to solve this problem using php itself but using shell_exec() to run the fully form curl command actually worked. So I have stuck to that implementation.
$cmd = "curl https://upload.box.com/api/2.0/files/content \
-H \"Authorization: Bearer $access_token\" -X POST \
-F attributes='{\"name\":\"$dest_name\",\"parent\": {\"id\":\"$parent_id\"}}' \
-F file=#\"$filePath\"";
$result=shell_exec($cmd);
return result;
I hope this helps somebody.
http_code=400 Bad Request.
Try to set your header enctype='multipart/form-data',as upload file use form.
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.
more php.net

calling CURL with POST data and headers on command line

I am using RESTAPI to communicate php client with django server. I have posted json data. The php code is
$arr=array("username"=>"dtthtdas45",
"password"=>"123456",
"email"=>"ramg#ram.com",
"is_active"=>"1",
"is_staff"=>"1",
"is_superuser"=>"1",
"promo_code"=>"1212121",
"gender"=>"m",
"birth_year"=>"1991",
"zip"=>"77707",
"first_name"=>"john",
"last_name"=>"doe",
"current_state"=>"1"
);
echo $data_string= json_encode($arr);
$ch = curl_init('http://localhost:8000/api/ecp/user/?format=json');
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);
How can i call same URL using command line only?
I tried the folowing
curl -H 'Content-Type: application/json' -X POST -d '{"username": "dtthtdas45", "password": "123456","email":"email#email.com","is_active":"1","is_staff":"1","is_superuser",promo_code":"1212121","gender":"m","birth_year":"1991","zip":"77707","first_name":"john","last_name":"doe","current_state":"1"}' http://localhost:8000/api/ecp/user/?format=json
but no luck , it shows the folowing error
curl: (6) Couldn't resolve host 'application'
curl: (6) Couldn't resolve host 'dtthtdas45,'
curl: (6) Couldn't resolve host 'password:'
How can i call same URL using command line only?
I didn't write out all the data pairs, but the following should get you started. I suggest reading more on curl
curl -H 'Content-Type: application/json' -X POST -d '{"username": "dtthtdas45", "password": "123456"}' http://localhost:8000/api/ecp/user/?format=json
Note: Assuming you are doing this for more endpoints, you might want to check out a tool like resty.

Categories