Construct a PHP POST request with binary data - php

I'm trying to construct a PHP POST request that includes some binary data, following on from a previous StackOverflow question. The data is being submitted to this API call: http://www.cyclestreets.net/api/#addphoto
This is my PHP code:
$file = $_FILES['mediaupload'];
$file_field="#$file[tmp_name]";
$fields = array(
'mediaupload'=>$file_field,
'username'=>urlencode($_POST["username"]),
'password'=>urlencode($_POST["password"]),
'latitude'=>urlencode($_POST["latitude"]),
'longitude'=>urlencode($_POST["longitude"]),
'datetime'=>urlencode($_POST["datetime"]),
'category'=>urlencode($_POST["category"]),
'metacategory'=>urlencode($_POST["metacategory"]),
'caption'=>urlencode($_POST["description"])
);
$fields_string = http_build_query($fields);
echo 'FIELDS STRING: ' . $fields_string;
$url = 'https://www.cyclestreets.net/api/addphoto.json?key=$key';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec ($ch);
This is what my PHP file outputs:
FIELDS STRING: mediaupload=%40%2Fprivate%2Fvar%2Ftmp%2FphpHjfkRP&username=testing&password=testing&latitude=auto&longitude=auto&datetime=auto&category=cycleparking&metacategory=good&caption=
API RESPONSE: {"request":{"datetime":"1309886656"},"error":{"code":"unknown","message":"The photo was received successfully, but an error occurred while processing it."},"result":{}}
I believe this means that everything else about the request is OK, apart from the format of the binary data. Can anyone tell me what I am doing wrong?

CURL can accept a raw array of key=>value pairs for POST fields. There's no need to do all that urlencode() and http_build_query() stuff. Most likely the # in the array is being mangled into %40, so CURL doesn't see it as a file upload attempt.
$fields = array(
'mediaupload'=>$file_field,
'username'=> $_POST["username"),
etc...
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields);

The http_build_query function generates a URL encoded query string which means that the "#file.ext" is URL encoded in the output as a string and cURL doesn't know that you're trying to upload a file.
My advice would be not to include the file to upload in the http_build_query call and included manually in the CURLOPT_POSTFIELDS.
$file = $_FILES['mediaupload'];
$file_field="#$file[tmp_name]";
$fields = array(
'username'=>urlencode($_POST["username"]),
'password'=>urlencode($_POST["password"]),
'latitude'=>urlencode($_POST["latitude"]),
'longitude'=>urlencode($_POST["longitude"]),
'datetime'=>urlencode($_POST["datetime"]),
'category'=>urlencode($_POST["category"]),
'metacategory'=>urlencode($_POST["metacategory"]),
'caption'=>urlencode($_POST["description"])
);
$fields_string = http_build_query($fields);
echo 'FIELDS STRING: ' . $fields_string;
$url = 'https://www.cyclestreets.net/api/addphoto.json?key=$key';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS, 'mediaupload=' . $file_field . '&' . $fields_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec ($ch);

Related

Got this from a API using curl

Trying to add some kind of value to each data point so I can send the response (numbers only) to an existing table . I've been searching online and no CURL API response seems to be this simple so I can find an answer. (sorry new to this, don't know the "lingo")
This is the response I've been able to echo on screen.
"{"price": 2049.27, "change_point": -5.76, "change_percentage": -0.28, "total_vol": "1.27M"}"
rest of php below
<html>
<?php
$url = 'https://realstonks.p.rapidapi.com/';
$collection_name = $_REQUEST["stock_name"];
$request_url = $url . '/' . $collection_name;
$curl = curl_init($request_url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
'X-RapidAPI-Host: www.xyz.com',
'X-RapidAPI-Key: xxxxxxxxxxxxxxxxxxx',
'Content-Type: application/json']);
$response = curl_exec($curl);
curl_close($curl);
//Uncomment bellow to show data on screen
echo $response . PHP_EOL;
enter code here
//var_dump(json_decode($json));
//var_dump(json_decode($json, true));
// Initiate curl
$ch = curl_init();
// Will return the response, if false it print the response
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Set the url
curl_setopt($ch, CURLOPT_URL,$url);
// Execute
$result=curl_exec($ch);
// Closing
curl_close($ch);
?>
I'm not much into PHP but here to here. If I'm not mistaken it, I think you want to store $response in <td> element. This resource can help https://www.daniweb.com/programming/web-development/threads/428730/how-to-display-php-variable-in-html

PHP Api Receiving JSON data

I am trying to make an API with PHP and JSON, however I am stuck on extracting the JSON on the receiving/API side of the request.
So I am doing this on the client end of my transaction:
$data = array("test" => "test");
$data_string = json_encode($data);
$ch = curl_init('https://..../api/v1/functions? key=TPO4X2yCobCJ633&aid=9&action=add');
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))
);
$return = curl_exec($ch);
But how do I receive and extract the POSTed data on the server (receiving) side of the transaction (inside my API)?
Summary:
What i mean is i have a client that is sending a JSON file to the API now i what i don't understand is how can i get the API side to see and extract/see the data
On the receiving side you need to read from the PHP input stream, then decode:
<?php
// read the incoming POST body (the JSON)
$input = file_get_contents('php://input');
// decode/unserialize it back into a PHP data structure
$data = json_decode($input);
// $data is now the same thing it was line 1 of your given sample code
If you wanted to be more succinct, you could obviously just nest those calls:
<?php
$data = json_decode(file_get_contents('php://input'));

PHP curl not sending post params

I have an online form to submit data as http post.
If no data is send as post , it will return the following error message
We are sorry, the form that you have submitted is invalid or no longer exists.
I am using the following code to send http post data using curl.But I am always getting the error message as output.
How to resolve this issue.Did I miss anything.I printed the curl request, and the post parameters are not sent.How can I fix this?
My code is given below
function curlUsingPost($url, $data)
{
$content_type = 'application/x-www-form-urlencoded';
if(empty($url) OR empty($data))
{
return 'Error: invalid Url or Data';
}
//url-ify the data for the POST
$fields_string = '';
foreach($data as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
$fields_string = http_build_query($data).'\n';
echo $fields_string;
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
// curl_setopt($ch, CURLOPT_HTTPHEADER, ['Accept: ' . $content_type]);
curl_setopt($ch, CURLOPT_HTTPHEADER,array($content_type));
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,true);
curl_setopt( $curl_handle, CURLOPT_HTTPHEADER, array( 'Expect:' ) );
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,10); # timeout after 10 seconds, you can increase it
//curl_setopt($ch,CURLOPT_HEADER,false);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); # Set curl to return the data instead of printing it to the browser.
curl_setopt($ch, CURLOPT_USERAGENT , "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)"); # Some server may refuse your request if you dont pass user agent
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$info = curl_getinfo($ch);
print_r($info );
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
return $result;
}
$url = 'office.promptip.com:8443/his1.max/Services/Webform.aspx?request=submitwebform&token=202D36560E444E466658461615120F75411B09634C696C6F79454E795E7C7A5154505645414F456C584C17101B443D431D0B654D66686D7C454E795E2D7E5152565341404145625E4213141E4273421E5E66486B666F2A464B7A5B79785F54520645444F15635C454516134422421A0D664A3D68687C454E79587F7D5F52575714424043635E1611181D16704D1D0E654F69696F2A474A7A0A78785807525E45414E406350424016134422421A0D374C6F686C7C44482F59787D5E530150104218426D584316181A4177411B0F';
//echo $url;
$data = [
'C0IFirstName' => 'John Doe',
'C1ILastName' => 'Doe John',
'C2IPosition' =>'Father-Guardian',
'U3I80'=>'8129020464',
'U4I150'=>'johndoe#johndoe.com',
'U5I79'=>'This is the message buddy',
'U6I102' => 'Ann',
'U7I105' =>'Doe',
'U8I52' =>'FS1',
'C9IClientId'=> rand ( 0,100000 ),
'U10I21'=>'Website-Enquiry Form'
];
echo curlUsingPost($url,$data);
Solution
Add this to your curl request:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
And replace & with & in URL you're requesting:
$url = 'office.promptip.com:8443/his1.max/Services/Webform.aspx?request=submitwebform&token=202D36560E444E466658461615120F75411B09634C696C6F79454E795E7C7A5154505645414F456C584C17101B443D431D0B654D66686D7C454E795E2D7E5152565341404145625E4213141E4273421E5E66486B666F2A464B7A5B79785F54520645444F15635C454516134422421A0D664A3D68687C454E79587F7D5F52575714424043635E1611181D16704D1D0E654F69696F2A474A7A0A78785807525E45414E406350424016134422421A0D374C6F686C7C44482F59787D5E530150104218426D584316181A4177411B0F';
Explenation
At first, you're requesting wrong URL, which was probably copied from some HTML documentation. Normally a & entity would be replaced by & char by HTML interpreter, but this does not work with curl and you have to replace the entity manually.
Also the server returns
We are sorry, the form that you have submitted is invalid or no
longer exists.
for each end every request in response body. But for successfull request it also provides a Location header. Normally browser would follow this location, make a second request and display success message. You have to tell cURL to do exactly the same with curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true).

how to post xml with curl with php GET variables?

the script will post xml content to a url, and i need to include the php GET variables (eg. $RegionId), pls advise how to.
$RegionId = $_GET["RegionId"];
// xml data
$xml_data ='<AvailabilitySearch>
<RegionId xmlns="http://www.reservwire.com/namespace/WebServices/Xml">$RegionId</RegionId>
<HotelId xmlns="http://www.reservwire.com/namespace/WebServices/Xml">0</HotelId>
<HotelStayDetails xmlns="http://www.reservwire.com/namespace/WebServices/Xml">
</AvailabilitySearch>
';
// assigning url and posting with curl
$URL = "http://roomsxmldemo.com/RXLStagingServices/ASMX/XmlService.asmx";
$ch = curl_init($URL);
............
............
............
$RegionId is not posted on the script, how to use the GET or POST variable on that xml content?
Hope this will help You
$RegionId = $_GET["RegionId"];
// xml data
$xml_data ='<?xml version="1.0" encoding="UTF-8"?><AvailabilitySearch>
<RegionId xmlns="http://www.reservwire.com/namespace/WebServices/Xml">{$RegionId}</RegionId>
<HotelId xmlns="http://www.reservwire.com/namespace/WebServices/Xml">0</HotelId>
<HotelStayDetails xmlns="http://www.reservwire.com/namespace/WebServices/Xml">
</AvailabilitySearch>
';
// assigning url and posting with curl
$URL = "http://roomsxmldemo.com/RXLStagingServices/ASMX/XmlService.asmx";
$headers = array(
"Content-type: text/xml",
"Content-length: " . strlen($xml_data),
"Connection: close",
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$UR);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_data);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$data = curl_exec($ch);
curl_close($ch);
echo $data;
Just add your GET vars to url.
$URL = "http://roomsxmldemo.com/RXLStagingServices/ASMX/XmlService.asmx?var1=val1&var2=val2";
Well, merely you can wrap your xml content in double quotes and substitute necessary variables.
$id = (isset($_GET['id'])) ? $_GET['id'] : '';
xml_data = "<AvailabilitySearch>
<RegionId xmlns=\"http://www.reservwire.com/namespace/WebServices/Xml\">$rid</RegionId>
<HotelId xmlns=\"http://www.reservwire.com/namespace/WebServices/Xml\">0</HotelId>
<HotelStayDetails xmlns=\"http://www.reservwire.com/namespace/WebServices/Xml\">
</AvailabilitySearch>";
Value of $id variable will be in xml content. And you can post this message. But, don't forget to shield inner double quotes with additional slashes in your xml.

Executing Curl with PHP

I'm trying to use Docverter to convert LaTeX/markdown files to PDF but am having trouble using PHP to do CURL to access Docverter via their API. I'm know I'm not a total idiot b/c i can get this to work adapting the shell script in this Docverter example and running from command line (Mac OSX).
Using PHP's exec():
$url=$_SERVER["DOCUMENT_ROOT"];
$file='/markdown.md';
$output= $url.'/markdown_to_pdf.pdf';
$command="curl --form from=markdown \
--form to=pdf \
--form input_files[]=#".$url.$file." \
http://c.docverter.com/convert > ".$output;
exec("$command");
This gives no error messages but doesn't work. Is there a path issue somewhere?
UPDATE Based on #John's suggestion, here's an example using PHP's curl_exec() adapted from here. Unfortunately this also doesn't work though at least it gives error messages.
$url = 'http://c.docverter.com/convert';
$fields_string ='';
$fields = array('from' => 'markdown',
'to' => 'pdf',
'input_files[]' => $_SERVER['DOCUMENT_ROOT'].'/markdown.md',
);
//url-ify the data for the POST
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string, '&');
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
I solved my own problem. There were two main problems with the above code:
1) The $fields array was incorrectly formatted for the input_files[]. It needed a #/ and mime-type declaration (see code below)
2) The curl_exec() output (the actual newly created file contents) needed to be returned and not just true/false which is this function's default behavior. This is accomplished by setting the curl option curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); (see code below).
Full working example
//set POST variables
$url = 'http://c.docverter.com/convert';
$fields = array('from' => 'markdown',
'to' => 'pdf',
'input_files[]' => "#/".realpath('markdown.md').";type=text/x-markdown; charset=UTF-8"
);
//open connection
$ch = curl_init();
//set options
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: multipart/form-data"));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //needed so that the $result=curl_exec() output is the file and isn't just true/false
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
//write to file
$fp = fopen('uploads/result.pdf', 'w'); //make sure the directory markdown.md is in and the result.pdf will go to has proper permissions
fwrite($fp, $result);
fclose($fp);

Categories