Sending POST data without form - php

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)

Related

How to submit a form of a html page using php

i need to know if is possible to load an html page and submit the form inside this page using php. so something like:
<?php
$html = fopen("http://www.mysite.com","r");
//get position of form...
...
//submit it
?>
is possible? can someone help me? thanks!!!
EDIT:
i have to submit this form
https://annunci.ebay.it/pubblica-annuncio
my problem is that in this page there is an image upload and i don't know how to do that using php( scraping it )
You can also use curl to POST to any URL, for instance the form's action url.
$ch = curl_init('http://example.com/form_action.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, array('your' => 'data', 'goes' => 'here');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
This will call the URL http://example.com/form_action.php as if it was called from a form with 'your' set to value 'data' and 'goes' set to value 'here'.
To find out the URL you need to POST, you can inspect source code. When doing that, check the "name" atribute on the <input> tags you want to send.
EDIT: If the POST url and the fields can change, you should check #Adan's answer.
Basically this is what you need to do
1- Get the content of the HTML page using file_get_contents() (bearing in mind the security risks)
2- Parse the HTML using DOMDocument
3- Get the form's attributes, most importantly (ACTION, METHOD) using DOMDocument
4- Get the form's fields' names using DOMDocument
5- Then send to the ACTION url using the method METHOD a request with the data you want replacing the fields using cURL
you can use curl for getting page in php. as mentioned in answer #Lumbendil. For parsing the HTML you can use libraries like
http://simplehtmldom.sourceforge.net/
Or you can use
http://code.google.com/p/phpquery/
As another option, which would be more clean, you could use the eBay API. It provides methods to add new items, and it probably has already built libraries for php, such as the PHP Accelerator toolkit for eBay.
I am providing a code that I got from net to get the contents of a page. After that you can use jquery(maybe) to force the submit function.
$url = "URL OF YOUR PAGE"; // I have tested page from same server
$lines = file( $url );
foreach( $lines as $line_num => $line ) {
$line = htmlspecialchars( $line );
$line = str_replace( "<", '<span><', $line );
$line = str_replace( ">", '></span>', $line );
$line = str_replace( "<!–", '<em><!–', $line );
$line = str_replace( "–>", '–></em>', $line );
echo "<span class=\"linenumber\">Line <strong>$line_num </strong></span> : " . $line . "<br/>\n";
}
The above code gave me contents from another page on same server. Now you have to find a way around to check if a form exist and then ; force submit that form.

HTML/PHP Post method to different server

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

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.

CURL grab information and log in with it

i got a problem.
i want to log in a website with CURL, but the page generates a key, which is in a hidden field. So I have to grab the value of the hidden field... after that i have to submit the password, the email AND the the grabbed key.
Is that possible?
hope you understand
Thanks
----edit----
if the page reload, there's a new key in the hidden field.. and the old one do not work
Yes, it's possible. The basic steps would be:
1. Fetch form
2. Run returned data through DOMdocument to extract the hidden form field's value
3. Post login data, including the key value from step #2
4. ???
5. Profit
Yes, it is.
Load the page contents into a variable (eg. $contents = file_get_contents(...);).
Now, parse it so you can get the hidden key (eg. $matches = preg_match(..., ...); $key = $matches[1];).
Now, post the request using the hidden key (eg. $context = streamcontextcreate(...); $data = file_get_contents(..., false, $context);).
Yes, it is possible.
You can even grab the page with
$source = htmlspecialchars(file_get_contents($url));
Then use strpos, substr and so on to get information of that field (that's the easiest way)
Then just POST it with this function
$urltopost = $url
$datatopost = array ($name => $value);
$ch = curl_init ($urltopost);
curl_setopt ($ch, CURLOPT_POST, true);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $datatopost);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
$returndata = htmlspecialchars(curl_exec ($ch));

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.

Categories