PHP CURL Submit Form - php

I know this topic has been widely discussed but in this instance I cannot get cURL to submit my simple form and I cannot see why, although I am sure it is obvious. I have tried many different cURL POST data examples found on StackOverflow but none seem to work.
My current idea is that my form action in this case is the problem because it is not, as far as I understand, the real action which posts the data. I have tried various tools to intercept the headers but all I see is the form action I currently have.
I am trying to use cURL to submit the contact form here, http://www.alpinewebdesign.co.uk/
Here is my latest attempt (in which I have included all the hidden fields and tried unsuccessfully I think to set a different header type).
//create array of data to be posted
$post_data['mact'] = 'FormBuilder,m62b34,default,1';
$post_data['m62b34returnid'] = '15';
$post_data['page'] = '15';
$post_data['m62b34fbrp_callcount'] = '1';
$post_data['m62b34form_id'] = '4';
$post_data['m62b34fbrp_continue'] = '2';
$post_data['m62b34fbrp_done'] = '1';
$post_data['name'] = 'Name';
$post_data['email'] = 'email#email.com';
$post_data['message'] = 'Message';
$post_data['m62b34fbrp_submit'] = 'Send';
//traverse array and prepare data for posting (key1=value1)
foreach ( $post_data as $key => $value) {
$post_items[] = $key . '=' . $value;
}
//create the final string to be posted using implode()
$post_string = implode ('&', $post_items);
//create cURL connection
$curl_connection =
curl_init('http://www.alpinewebdesign.co.uk');
//set options
curl_setopt($curl_connection, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl_connection, CURLOPT_USERAGENT,
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
curl_setopt($curl_connection, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_connection, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl_connection, CURLOPT_FOLLOWLOCATION, 1);
$headers = array();
$headers[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8';
$headers[] = 'Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryM4YWvE6kIZAIC8vY';
curl_setopt($curl_connection, CURLOPT_HTTPHEADER, $headers);
//set data to be posted
curl_setopt($curl_connection, CURLOPT_POSTFIELDS, $post_string);
//perform our request
$result = curl_exec($curl_connection);
//show information regarding the request
print_r(curl_getinfo($curl_connection));
echo curl_errno($curl_connection) . '-' .
curl_error($curl_connection);
//close the connection
curl_close($curl_connection);
Can anyone see the problem?
Thanks

Add
curl_setopt($curl_connection, CURLOPT_POST, true);

Maybe this can help you:
Firstly check if cURL library is enabled on your server:
<?=phpinfo();?>
Then try to prepare CURLOPT options as Array (also prepare the "form-data" query)
function prepareCurlOptions($url, $data, $headers)
{
$boundary = uniqid();
$post_fields = "-----" . $boundary . "\r\n";
$separate = count($data);
foreach($data as $k=>$v)
{
$post_fields .= "Content-Disposition: form-data; name=\"$k\"\r\n\r\n$v\r\n-----" . $boundary;
// add \r\n separator after each field, except last one
if( --$separate > 0 )
{
$post_fields .= "\r\n";
}
}
$post_fields .= "--";
return array(
CURLOPT_URL => $url,
CURLOPT_POSTFIELDS => $post_fields,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_SSL_VERIFYPEER => FALSE,
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
);
}
And then set all additional options by curl_setopt_array, for example:
$url = 'http://www.alpinewebdesign.co.uk';
$post_data = array();
$post_data['name'] = 'Name';
$post_data['email'] = 'email#email.com';
$post_data['message'] = 'Message';
// ...
$headers = array();
$headers[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8';
// ...
curl_setopt_array($curl_connection , prepareCurlOptions($url, $post_data, $headers));
Renember to make sure that Boundary for headers are the same as for the $post_data fields. For example:
$headers[] = "content-type: multipart/form-data; boundary=---".$boundary"

Related

Call to endpoint fails returns string(69) "Error: This method supports only xml ExceptionType: System.Exception"

I am trying to make this code return the data at the endpoint but it returns this error string(69) "Error: This method supports only XML ExceptionType: System. Exception". I have tried checking what it means but couldn't figure it out.
The code is broken into 2 parts, the first part which dumps the $result array variable works well. The second dump of $resResult is what's giving the problem. This means that call to the first endpoint works well but calling the second keeps failing.
Code PHP
<?php
$username = '73ec71d0a809/Markettrendsintl';
$password = 'Market#123';
$surveyID = '47f2-bfe4-db0eb01d1049';
$endpoint = 'https://api.dooblo.net/newapi/SurveyInterviewIDs?surveyIDs='.$surveyID;
$credentials = base64_encode("$username:$password");
$headers = [];
$headers[] = "Authorization: Basic {$credentials}";
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
$headers[] = 'Cache-Control: no-cache';
$headers1 = [];
$headers1[] = "Authorization: Basic {$credentials}";
$headers1[] = 'Content-Type: text/xml';
$headers1[] = 'Cache-Control: no-cache';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result[] = curl_exec($ch);
/*---------New Code -----------------*/
$counter = 0;
$interviewIdsInCurPack = '';
for ($i=0; $i < count($result); $i++) {
$interviewIdsInCurPack = sprintf("{0},{1}", $interviewIdsInCurPack, $result[$i]);
$counter += 1;
$lastInterviewID = $i==$result[$i];
if ($counter == 99 || $lastInterviewID) {
$interviewIdsInCurPack = substr_replace($interviewIdsInCurPack, 0, 1);
$urlInterviewData = sprintf("https://api.dooblo.net/newapi/SurveyInterviewData?subjectIDs={0}&surveyID={1}&onlyHeaders=false&includeNulls=false", $interviewIdsInCurPack, $surveyID);
// print($urlInterviewData);
$sender = curl_init();
curl_setopt($sender, CURLOPT_URL, $urlInterviewData);
curl_setopt($sender, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($sender, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($sender, CURLOPT_HTTPHEADER, $headers1);
$resResult = curl_exec($sender);
var_dump($resResult);
}
}
According to the documentation of Dooblo:
However, please keep in mind that for some operations that return either interview data or survey data in them, only XML will be supported as an output format. If you try to call these with JSON as format you will receive an error: “Error: This method supports only xml” from the API
That last part is exactly your error message. According to their REST API example code you can set the desired output-format using the HTTP Accept header:
client.AddDefaultHeader("Accept", "text/xml");
client.AddDefaultHeader("Accept-Charset", "utf-8");
They are using a different client there, within PHP you do that as followed:
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Accept: text/html',
'Accept-Charset: utf-8'
));

how to convert command line curl to php curl

I need to convert this command line cURL into a php cURL and echo the result
curl -H "Content-Type: application/json" -d '{ "code":"<code>", "client_id": "<client_id>", "client_secret": "<client_secret>"}' https://www.example.com/oauth/access_token
how can this be done?
Try this simple approach:
$data = array("code"=>"123", "client_id"=> "123", "client_secret"=> "123");
$data_string = json_encode($data);
$ch = curl_init('https://www.example.com/oauth/access_token');
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);
Replace 123 with your values. Here is the manual for curl_setopt()
Something like this should work, assuming you need to POST the data to the URL:
<?php
// URL that the data will be POSTed to
$curl_url = 'https://www.example.com/oauth/access_token';
// Convert the data into an array
$curl_data_arr = array('{ "code":"<code>", "client_id": "<client_id>", "client_secret": "<client_secret>"}');
// Prepare to post as an array
$curl_post_fields = array();
foreach ($curl_data_arr as $key => $value) {
// Assuming you need the values url encoded, this is an easy way
$curl_post_fields[] = $key . '=' . urlencode($value);
}
$curl_header = array('Content-Type: application/json');
$curl_array = array(
CURLOPT_URL => $curl_url,
CURLOPT_HTTPHEADER => $curl_header,
CURLOPT_POSTFIELDS => implode('&', $curl_post_fields),
CURLOPT_POST => TRUE,
CURLOPT_RETURNTRANSFER => TRUE,
);
// Initialize cURL
$curl = curl_init();
// Tell cURL to use the array of options we just set up
curl_setopt_array($curl, $curl_array);
// Assign the result to $data
$data = curl_exec($curl);
// Empty variable (at first) to avoid errors being displayed
$result = '';
// Check for errors
if ($error = curl_error($curl)) {
// If there's an error, assign its value to $result
$result = $error;
}
curl_close($curl);
// If there's no errors...
if (empty($error)) {
// ... instead assign the value of $data to $result
$result = $data;
}
echo $result;

php fetching page using http post

I have to fetch exam results from the page http://cbseresults.nic.in/class1211/cbse122012.htm
Sampleroll number is 4623447.
They are using http post to post the form data.I wrote the following code to post data.But it is not providing the needed results.I am posting the needed cookies and post variables.But still I am not getting the output.What change should I make for send_post function,so that it will be working.Here is my code
echo cbse12_data_extractor(4623447);
function cbse12_data_extractor($regNo) {
$source_url = 'http://cbseresults.nic.in/class1211/cbse122012.asp';
$post_vars = array('regno'=>$regNo);
$cookies = array('_tb_pingSent'=>1);
// $extraHeaders = array('Host'=>'http://cbseresults.nic.in');
return send_post($source_url,$post_vars,$cookies);
}
function send_post( $url, $data ,$cookies='',$extraHeaders = '') //sends data array(param=>val,...) to the page $url in post method and returns the reply string
{
$post = http_build_query( $data );
$header = "Accept-language: en\r\n".
"Content-Type: application/x-www-form-urlencoded\r\n" .
"Content-Length: " . strlen( $post ) .
"\r\nUser-agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n";
if($extraHeaders) {
foreach($extraHeaders as $headerN => $val) {
$header = $header.$headerN.': '.$val."\r\n";
}
}
if($cookies) {
$cookieArr = array();
foreach($cookies as $cookie => $value) {
array_push($cookieArr,$cookie.'='.$value);
}
$cookieStr = "Cookie: ".implode('; ',$cookieArr)."\r\n";
$header = $header.$cookieStr;
}
$context = stream_context_create( array(
"http" => array(
"method" => "POST",
"header" => $header,
"content" => $post
)
) );
//echo $header;
$page = file_get_contents( $url, false, $context );
return $page;
}
You can' send POST data using file_get_contents. Use CURL for this task
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,your_parameters);
// receive server response ...
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec ($ch);

PHP cURL POST returns a 415 - Unsupported Media Type

I've got a simple PHP script that sends an HTTP POST request via cURL, and expects a json string in response (would have loved to use an existing library like pecl_http/HTTPRequest for this, but can't). The call consistently fails with a 415 error - Unsupported Media Type. I think I'm not configuring cURL correctly, but after much searching, I can't find out what I'm doing wrong. Here's some code:
class URLRequest
{
public $url;
public $headers;
public $params;
public $body;
public $expectedFormat;
public $method;
public function URLRequest($aUrl, array $aHeaders, array $aParams, $aFormat = "json", $isPost = false, $aBody = "+")
{
$this->url = $aUrl;
$this->headers = $aHeaders;
$this->params = $aParams;
$this->expectedFormat = $aFormat;
$this->method = ($isPost ? "POST" : "GET");
$this->body = $aBody;
}
public function exec()
{
$queryStr = "?";
foreach($this->params as $key=>$val)
$queryStr .= $key . "=" . $val . "&";
//trim the last '&'
$queryStr = rtrim($queryStr, "&");
$url = $this->url . $queryStr;
$request = curl_init();
curl_setopt($request, CURLOPT_URL, $url);
curl_setopt($request, CURLOPT_HEADER, 1);
curl_setopt($request, CURLOPT_HTTPHEADER, $this->headers);
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1);
//curl_setopt($request, CURLOPT_SSL_VERIFYPEER, false);
if($this->method == "POST")
{
curl_setopt($request, CURLOPT_POST, 1);
curl_setopt($request, CURLOPT_POSTFIELDS, $this->body);
//this prevents an additions code 100 from getting returned
//found it in some forum - seems kind of hacky
curl_setopt($request, CURLOPT_HTTPHEADER, array("Expect:"));
}
$response = curl_exec($request);
curl_close($request);
preg_match("%(?<=HTTP/[0-9]\.[0-9] )[0-9]+%", $response, $code);
$resp = "";
if($this->expectedFormat == "json")
{
//parse response
}
elseif($this->expectedFormat == "xml")
{
//parse response
}
return $resp;
}
}
$url = "http://mydomain.com/myrestcall";
$query = array( "arg_1" => "test001",
"arg_2" => "test002",
"arg_3" => "test003");
$headers = array( "Accept-Encoding" => "gzip",
"Content-Type" => "application/json",
"Accept" => "application/json",
"custom_header_1" => "test011",
"custom_header_2" => "test012",
"custom_header_3" => "test013");
$body = array( "body_arg_1" => "test021",
"body_arg_2" => array("test022", "test023"),
"body_arg_3" => "test024");
$request = new URLRequest($url, $headers, $query, "json", true, $body);
$response = $request->exec();
...and the response:
HTTP/1.1 415 Unsupported Media Type
Server: Apache-Coyote/1.1
X-Powered-By: Servlet 2.5; JBoss-5.0/JBossWeb-2.1
Content-Type: text/html;charset=utf-8
Content-Length: 1047
Date: Mon, 18 Jun 2012 16:30:44 GMT
<html><head><title>JBoss Web/2.1.3.GA - Error report</title></head><body><h1>HTTP Status 415 - </h1><p><b>type</b> Status report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>The server refused this request because the request entity is in a format not supported by the requested resource for the requested method ().</u></p><h3>JBoss Web/2.1.3.GA</h3></body></html>
Any insights or ideas?
Thanks in advance!
Problem solved! Here's the issue:
Sending an associative-array of headers DOES NOT WORK with cURL. There are several forums scattered around that show examples using an associative array for headers. DON'T DO IT!
The correct way (which is also scattered around the internets, but that I'm too dense to have noticed) is to construct your header key/value pairs as strings, and pass a standard array of these strings when setting the CURLOPT_HTTPHEADER option.
So in summary,
WRONG:
$headers = array( "Accept-Encoding" => "gzip",
"Content-Type" => "application/json",
"custom_header_1" => "test011",
"custom_header_2" => "test012",
"custom_header_3" => "test013");
RIGHT:
$headers = array( "Accept-Encoding: gzip",
"Content-Type: application/json",
"custom_header_1: test011",
"custom_header_2: test012",
"custom_header_3: test013");
I hope this comes in handy to some other noble doofus down the road before they waste as much time debugging as I did.
If I had to guess, I would assume that the same rule applies to the POST body key/value pairs as well, which is why #drew010 's comment about using http_build_query() or json_encode() to stringify your message body is a great idea as well.
Thanks to everyone for your very useful comments, and for you time and consideration. In the end, a side by side comparison of the http traffic (captured via Wireshark) revealed the issue.
Thanks!
I think the problem is that you are passing an array as the CURLOPT_POSTFIELDS option. By passing an array, this forces the POST request to use multipart/form-data when the server is probably expecting application/x-www-form-urlencoded.
Try changing
curl_setopt($request, CURLOPT_POSTFIELDS, $this->body);
to
curl_setopt($request, CURLOPT_POSTFIELDS, http_build_query($this->body));
See http_build_query for more information and also this answer: My cURL request confuses some servers?
I had the same problem and I fixed changing the header.
My code:
$authorization = 'authorization: Bearer '.trim($apiKey);
$header = [
'Content-Type: application/json',
$authorization
];
curl_setopt($session, CURLOPT_HTTPHEADER, $header);
I don't know why the array function doesn't work :
curl_setopt($session, CURLOPT_HTTPHEADER, array('Content-Type:
application/json',
$authorization));
This worked for me
$data ="data";
$headers = [
"Content-Type: application/json",
"X-Content-Type-Options:nosniff",
"Accept:application/json",
"Cache-Control:no-cache"
];
$auth = $USER . ":" . $PASSWORD;
$curl = curl_init();
curl_setopt($curl,CURLOPT_URL, $url);
curl_setopt($curl,CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl,CURLOPT_ENCODING, "");
curl_setopt($curl,CURLOPT_MAXREDIRS, 10);
curl_setopt($curl,CURLOPT_TIMEOUT, 0);
curl_setopt($curl,CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
curl_setopt($curl,CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl,CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($curl, CURLOPT_USERPWD, $auth);
curl_setopt($curl,CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($curl);

Multipart PUT upload using Curl and PHP to a REST endpoint

I need to HTTP PUT a csv file and some POST fields using multipart POST with PHP and Curl to a REST API endpoint.
The contents of the file upload is stored in a variable $list. The other end point is $url.
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_PUT, true);
$post = array(
//Other Post fields array
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$fh = fopen('php://memory', 'rw');
fwrite($fh, $list);
rewind($fh);
curl_setopt($ch, CURLOPT_INFILE, $fh);
curl_setopt($ch, CURLOPT_INFILESIZE, strlen($list));
$response = curl_exec($ch);
The above code seems to work the only problem is that the other end point requires a specific fieldname for the file upload. How do i set a filename ?
Am i doing something wrong ?
This is the PUT format they have mentioned on API
Content-Disposition: form-data; name="list[csv]"; filename="RackMultipart20110923-63966-hfpyg"
Content-Length: 33
Content-Type: text/csv
Content-Transfer-Encoding: binary
xxxx
yyyy
zzzz
-------------MultipartPost
Content-Disposition: form-data; name="list[list_type]"
Blacklist
-------------MultipartPost--
FYI that is multipart/form-data. You will need to build the body yourself I think, I don't think cURL could be made to build that sort of request with a PUT request. However, this is not a serious problem:
<?php
function recursive_array_mpfd ($array, $separator, &$output, $prefix = '') {
// Recurses through a multidimensional array and populates $output with a
// multipart/form-data string representing the data
foreach ($array as $key => $val) {
$name = ($prefix) ? $prefix."[".$key."]" : $key;
if (is_array($val)) {
recursive_array_mpfd($val, $separator, $output, $name);
} else {
$output .= "--$separator\r\n"
. "Content-Disposition: form-data; name=\"$name\"\r\n"
. "\r\n"
. "$val\r\n";
}
}
}
// This will hold the request body string
$requestBody = '';
// We'll need a separator
$separator = '-----'.md5(microtime()).'-----';
// First add the postfields
$post = array(
//Other Post fields array
);
recursive_array_mpfd($post, $separator, $requestBody);
// Now add the file
$list = "this,is,some,csv,data"; // The content of the file
$filename = "data.csv"; // The name of the file
$requestBody .= "--$separator\r\n"
. "Content-Disposition: form-data; name=\"list[list_type]\"; filename=\"$filename\"\r\n"
. "Content-Length: ".strlen($list)."\r\n"
. "Content-Type: text/csv\r\n"
. "Content-Transfer-Encoding: binary\r\n"
. "\r\n"
. "$list\r\n";
// Terminate the body
$requestBody .= "--$separator--";
// Let's go cURLing...
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: multipart/form-data; boundary="'.$separator.'"'
));
$response = curl_exec($ch);
If you have any problems with this, try echo $requestBody; before the cURL request and make sure it looks like you expect it to.

Categories