HTML/PHP Post method to different server - php

I want to create a POST method form that sends details to a PHP script on another server (ie, not its localhost). Is this even possible? I imagine GET is fine, so is POST possible?

<form method="POST" action="http://the.other.server.com/script.php">

If you want to do that on your server (i.e. you want your server to act as a proxy) you can use cURL for that.
//extract data from the post
extract($_POST);
//set POST variables
$url = 'http://domain.com/get-post.php';
$fields_string = "";
$fields = array(
'lname'=>urlencode($last_name), // Assuming there was something like $_POST[last_name]
'fname'=>urlencode($first_name)
);
//url-ify the data for the POST
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
$fields_string = 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);
However if you just simply want to send a POST request to another server, you can just change the action attribute:
<form action="http://some-other-server.com" method="POST">

There is another question on Stack Overflow that shows a better way to url-ify the variables. It is better because the method shown in the answer above breaks when you use nested associative arrays (aka hashes).
How do I use arrays in cURL POST requests
If you are really wanting to build that query string manually, you can. However, http_build_query will make your "url-ify the data for the POST" section unnecessary. – Benjamin Powers Nov 28 '12 at 2:48

Related

Collecting data with curl and sending it to a database through a form

I have searched everything I can think of to make this happen. I am trying to collect data through curl, then send that data to a form which submits it to the database. With the help of this blog and a pre existing product, I managed to get the following code
//extract data from the post
//set POST variables
$cookie_name = "drcuserid";
if(isset($_COOKIE[$cookie_name]))
{
$cookie = $_COOKIE[$cookie_name];
}
$url = 'http://dirtrif.com/test.php';
$fields['username'] = $vbulletin->userinfo[username];
$fields['userid'] = $vbulletin->userinfo[userid];
$fields['addontitle'] = $info['title'];
$fields['addonversion'] = $info['version'];
$fields['bburl'] = $vbulletin->options[bburl];
$fields['bbtitle'] = $vbulletin->options[bbtitle];
$fields['webmasteremail'] = $vbulletin->options[webmasteremail];
$fields['cookie'] = $_COOKIE[$cookie_name];
//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);
This is all uncharted territory to me, and I know it needs to be submitted to a form on test.php but I have no idea where to even start with it. Every example I have come across fails to include that part or even speak of it.
I am trying to get this data submitted to my database, then from there I can manage pulling the results. I know this is pretty demanding, but if anyone can point me in the right direction that would be awesome too. I'm not looking to be spoon-fed I do want to learn as I evolve.
***************Added**************
Just wanted to clarify the results I'm looking for would be a way to get these variables I defined, then send them to my URL I defined, Which would submit them to my database through a form, or really any other way of sending the results to my DB.
An Example of the output I am trying to achieve would be: (DATABASE TABLES) spacing didn't work out. Hope you understand.
username userid addontitle addonversion bburl
BOB 2 Product v1.0 somesite.com
I have read THIS which gave me more insight to working with curl. To answer one of my questions, curl is the form (at least what I gathered) Now on to seeing if I can figure out this posting it to my DB.

Scraping data from an internally-called AJAX address

I'm trying to get leagues data from this address:
http://www.10bet.com/sports/soccer/?utm_source=shp&utm_medium=sleft&utm_campaign=soccer
In that page, if you click on "Champions League" for example, in Firebug I see an AJAX call to this address:
http://www.10bet.com/pagemethods.aspx/GetLeaguesContent
The result is a JSON object which contains matches info from that league. However, when I get that page with cURL, even when I post exact parameters, I get a bunch of JavaScript code:
$url = 'http://www.10bet.com/pagemethods.aspx/GetLeaguesContent';
$fields = array(
'BranchID' => urlencode('1') ,
'LeaguesCollection' => urlencode('10098') ,
);
$fields_string = '';
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string, '&');
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
$result = curl_exec($ch);
curl_close($ch);
echo $result;
I took a quick look and I was able to discover the problem in about a minute. It's a missing request header. I'm not going to tell you which one but I will tell you how I discovered it so next time you can do it yourself.
First, install Charles proxy and run it. Open that page in Chrome. When the browser makes the request it will show up in Charles.
Now highlight the request in question and go down to 'Edit' on the right click menu. Just start removing the headers that you think might be the problem one at a time and re-execute the request. When it sends the javascript, you will know that the last header you removed was the one.

Filling form field

I want to fill a form field and submit it using CURL.The webpage has many form fields which are already filled so i do not want to touch these fields.
So is it possible to use curl and fill only the required field and submit it along with all other fields which are already filled ?
A full walkthrough (given the supplied HTML scrape text)
To customize you would simply add field names to the $fields_i_want array to specify all of the text field values you wanted to pull from the downloaded source text and change the URLs for retrieval and submission locations.
Also, a better alternative to file_get_contents() is curl. You can use the instructions on this SO post for how to retrieve remote text via curl.
// First, retrieve the remote source using file_get_contents()
$str = file_get_contents('http://www.example.com/');
$my_field_val = 'my_field_value';
$fields_i_want = array('audien', 'unifor');
$field_vals = array();
$field_string = '';
// Use DOM to parse the values you want from the form
$dom = new DOMDocument;
$dom->loadHTML($str);
// Get all the input field nodes
$inputs = $dom->getElementsByTagName('input');
// Iterate over the input fields and save the values we want to an array
foreach ($inputs as $input) {
$name = $input->getAttribute('name');
if (in_array($name, $fields_i_want)) {
$val = $input->getAttribute('value');
$field_vals[$name] = $val;
}
}
// append the field value we set ourselves to the list
$field_vals['my_field'] = $my_field_val;
foreach ($field_vals as $key => $val) {
$field_vals[$key] = urlencode($val)
}
// url-ify the data for the POST
foreach($fields as $key=>$value) {
$fields_string .= $key.'='.$value.'&';
}
rtrim($fields_string, '&');
// open connection
$ch = curl_init();
// POST the data to the form submission url
$submit_url = 'http://www.submitform.com';
// set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $submit_url);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
// execute post (returns TRUE on success or FALSE on failure)
$result = curl_exec($ch);
// close connection
curl_close($ch);
Depends how the form is initially populated.
If the pre-populated elements all use value="foo" then just grab the page (using curl), load it up in to a DOMDocument, fetch the <form> you're after and populate the field(s) you need, then pass it off as another request using a new cURL request (taking in to account the form's action and method attributes, as well as form data being sent off).
However, if they're populated with JS and you don't plan on writing the cURL request to mimic what you're doing on your browser, I don't see an easy way of mimicking JS actions, then populating, then sending it off.
Also, this doesn't take in to account any cookies that may be present. If you need those, you're going to have to store them from the first request and make sure to send them off in the actual submission call.
Not sure if it fits, but in order to check what are the required fields you need to parse the HTML and check for each input file and look for any required mention.
To parse the HTML, you can use some tools like:
http://framework.zend.com/manual/en/zend.dom.query.html
http://simplehtmldom.sourceforge.net/
With that tools, you can open the page, look for any required tags on the fields, and then decide with form field to submit.

How do I post to a form and populate a select multiple?

I'm doing something a bit strange here, I'm querying data out of my local database and posintg it to Salesforce form using cURL. The data posts correctly to Salesforce. However, the select multiple is not getting the correct values selected. See $sd["location"] below in my code:
//init curl
$ch = curl_init();
//setup the params
$url = 'https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8';
$oid = "HIDDEN";
//setup the superdelegate array
$sd = array();
$sd["oid"] = $oid;
$sd["retURL"] = "";
$sd["first_name"] = "1144asdfsadf4";
$sd["last_name"] = "SDFSD1111";
$sd["state"] = "IL";
$sd["location"] = '"Chicago","New York","California"'; //this is the value that submits to the select multiple
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($sd));
//post to Salesforce and then close the connection
curl_exec($ch);
curl_close($ch);
The select multiple is already setup in Salesforce with a 30 different locations. I'm trying to pass the cities that should be selected (Chicago, New York, California). Can you help me fix my code to get this to work correctly?
What you are trying to implement/duplicate is the non-standard (or "experimental" if you prefer) application/x-www-form-urlencoded format. The "x-" in the mime type denotes the fact that it is has not been officially standardized.
The most common application/x-www-form-urlencoded format I've encountered is as specified in the HTML 4 (and probably HTML 5) specification here. Which, when simplified, states that each successful control is paired with it's name and current value, in the order it appears in the form, and separated by the ampersand, "&". This would translate into a HTTP GET or POST method containing something like:
name=test&desc=some%20description&option=1&option=2&option=3
You should also use PHP's urlencode function on form names and values before passing it along in the appropriate location of the HTTP request in order to conform with RFC1738.
As a side note, PHP, though probably not alone, is an odd-ball in how it handles multiple values on a single post var. It follows the HTML suggested specification, but extends it to only consider a var as multiple if its name contains the PHP array append operator, e.g., formname[]. If you try to follow the HTML suggestion (see below) on a PHP script, it will overwrite the previous value on the name when accessing via the $_POST or $_GET superglobals.
I figured it out. This ended up doing it:
Sending as "value1;value2" doesn't work. i.e. implode(";", $array) or join() doesn't work.
Had to split the values like this in the POST string, oddly:
$post_string .= "&the_field=value1
$the_field=value2
$the_field=value3";
Now works fine.
$sd['location'] should be an array if its a multiple. For example:
$location = str_replace('"', '', '"Chicago","New York","California"');
$sd['location'] = explode(',', $location);
However you need to make sure you are not confusing the values with the labels. Salesforce will be expecting the value not the label so if salesforce is built with something like:
1 = Antwerp
2 = California
...
29 = Whatever
Then you need to pass the key values not the actual city names. I dunno what your salesforce stuff looks like so youll have to figure that out :-)
I'm also trying to send multiple select values to Salesforce, but my code looks slightly different and I'm not sure how to implement your solution. It's literally the only solution I can find on the net, so I'm hoping you can help me out. This is what my fields array looks like:
//set POST variables
$url = 'https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8';
$fields = array(
'oid'=>urlencode($oid),
'00NE0000003yZ9B'=>urlencode($Lead_Source_Email),
'00NE0000004hd4z'=>urlencode($Personal_Challenges),
'recordType'=>urlencode($recordType),
'retURL'=>urlencode($retURL),
'first_name'=>urlencode($first_name),
'last_name'=>urlencode($last_name),
'email'=>urlencode($email),
'phone'=>urlencode($phone),
//'00NE0000003uZ4G'=>urlencode($Contact_By),
'00NE0000003uZ9X'=>urlencode($Message)
);
$Personal_Challenges is the field from the select box with the multiple values. I honestly don't understand all of the code, but this is what follows:
//url-ify the data for the POST
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string,'&');
//print_r($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'd love any help you can give me! Sorry to ask this question in an answer, but apparently I can't directly message on StackOverflow.
Cheers!
I see this post is too old, but just in case:
we have to prepare string for it
curl_setopt($ch, CURLOPT_POSTFIELDS, $str_fields);
We can prepare array like:
$fields = array('f1' => 'v1', f2 =>['v21', 'v22', 'v23'], 'f3' =>'v3' );
$fields = http_build_query($fields);
it gives : f1=v1&f2%5B0%5D=v21&f2%5B1%5D=v22&f2%5B2%5D=v23&f3=v3
we need to clear chars like "%5B0%5D"
$str_fields=preg_replace("/(%5[A-F]\d{0,})/" ,"",$fields);
We get f1=v1&f2=v21&f2=v22&f2=v23&f3=v3
Thats all.

Sending POST data without form

Can i send for example a string or another piece of information to another .php file without it being exposed [thus not by GET but by POST conform to what i know] without using a form?
If you don't want your data to be seen by the user, use a PHP session.
Data in a post request is still accessible (and manipulable) by the user.
Checkout this tutorial on PHP Sessions.
You could use AJAX to send a POST request if you don't want forms.
Using jquery $.post method it is pretty simple:
$.post('/foo.php', { key1: 'value1', key2: 'value2' }, function(result) {
alert('successfully posted key1=value1&key2=value2 to foo.php');
});
Send your data with SESSION rather than post.
session_start();
$_SESSION['foo'] = "bar";
On the page where you recieve the request, if you absolutely need POST data (some weird logic), you can do this somwhere at the beginning:
$_POST['foo'] = $_SESSION['foo'];
The post data will be valid just the same as if it was sent with POST.
Then destroy the session (or just unset the fields if you need the session for other purposes).
It is important to destroy a session or unset the fields, because unlike POST, SESSION will remain valid until you explicitely destroy it or until the end of browser session. If you don't do it, you can observe some strange results. For example: you use sesson for filtering some data. The user switches the filter on and gets filtered data. After a while, he returns to the page and expects the filter to be reset, but it's not: he still sees filtered data.
Simply use: file_get_contents()
// building array of variables
$content = http_build_query(array(
'username' => 'value',
'password' => 'value'
));
// creating the context change POST to GET if that is relevant
$context = stream_context_create(array(
'http' => array(
'method' => 'POST',
'content' => $content, )));
$result = file_get_contents('http://www.example.com/page.php', null, $context);
//dumping the reuslt
var_dump($result);
Reference: my answer to a similar question:
have a look at the php documentation for theese functions you can send post reqeust using them.
fsockopen()
fputs()
or simply use a class like Zend_Http_Client which is also based on socket-conenctions.
also found a neat example using google...
function redir(data) {
document.getElementById('redirect').innerHTML = '<form style="display:none;" position="absolute" method="post" action="location.php"><input id="redirbtn" type="submit" name="value" value=' + data + '></form>';
document.getElementById('redirbtn').click();
}
<button onclick="redir('dataToBeSent');">Next Page</button>
<div id="redirect"></div>
You can use this method which creates a new hidden form whose "data" is sent by "post" to "location.php" when a button[Next Page] is clicked.
I would highly recommend using curl in such situation, file_get_content() does work but not at all times, and it could be troublesome to use it in some applications.
Though curl comes in different variations depending on what you want to send and in what method, here is the most common method of posting your data without HTML form using curl.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://example.com/request_uri');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$post = array(
'data1' => 'value1',
'data2' => $value2
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
//do what you want with the responce
var_dump($result)

Categories