How to submit a form using PHP (cURL, fsockopen)



How to submit a form using PHP

There are situations when you want to send data using POST to a URL, either local or remote. Why would you want to do this? Probably you want to submit data to an optin form, but without taking a valuable visitor away from your site. Or maybe you want to send data to several applications for various purposes, which would be impossible to do in the usual manner. So how can we deal with this problem?

Simulate submitting a form using cURL

So what is cURL anyway? cURL stands for “Client URL”, and it is a library of functions that can be used to connect and communicate to a wide range of servers, such as HTTP, FTP, telnet and so on. cURL also speaks HTTPS, so it can be used to communicate with secure servers.

What are we going to use are cURL HTTP capabilities. cURL supports POST and GET methods, file uploads, cookies, user/password authentications, even using proxy servers for connecting.

It can literally be used to programmatically simulate browsing behavior. It can connect to a remote site, login by posting username and password to the login form or by using HTTP authentication, then retrieve pages or upload files. All of this using pure PHP code.

So how do I use cURL to post data?

Begin by creating a new connection.

$curl_connection =
curl_init('http://www.domainname.com/target_url.php');

A new connection is created using curl_init() function, which takes as parameter the target URL where we want to post our data. The target URL is the same as the “action” parameters of a normal form, which would look like this:

<form method="post" action="http://www.domainname.com/target_url.php">

Now let’s set some options for our connection. We can do this using the curl_setopt() function. Go here for more information on curl_setopt() and a complete list of 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);

What options we set here?

First we set the connection timeout to 30 seconds, so we don’t have our script waiting indefinitely if the remote server fails to respond.

Then we set how cURL will identify itself to the remote server. Some servers will return different content for different browsers (or agents, such as spiders of the search engines), so we want our request to look like it is coming from a popular browser.

CURLOPT_RETURNTRANSFER set to true forces cURL not to display the output of the request, but return it as a string.

Then we set CURLOPT_SSL_VERIFYPEER option to false, so the request will not trigger an error in case of an invalid, expired or not signed SSL certificate.

Finally, we set CURLOPT_FOLLOWLOCATION to 1 to instruct cURL to follow “Location:” redirects found in the headers sent by the remote site.

Now we must prepare the data that we want to post. We can first store this in an array, with the key of an element being the same as the input name of a regular form, and the value being the value that we want to post for that field.

For example, if in a regular form we would have:

<input type="text" name="firstName" value="Name">
<input type="hidden" name="action" value="Register">

we add this to our array like this:

$post_data['firstName'] = 'Name';
$post_data['action'] = 'Register';

Do the same for every form field.

Data will be posted in the following format:

key1=value1&key2=value2

In order to format the data like this, we are going to create strings for each key-value pair (for example key1=value1), put them in another array ($post_items) then combine them in one string using PHP function implode() .

foreach ( $post_data as $key => $value) {
$post_items[] = $key . '=' . $value;
}
$post_string = implode ('&', $post_items);

Next, we need to tell cURL which string we want to post. For this, we use the CURLOPT_POSTFIELDS option.

curl_setopt($curl_connection, CURLOPT_POSTFIELDS, $post_string);

Finally, we execute the post, then close the connection.

$result = curl_exec($curl_connection);
curl_close($curl_connection);

By now, the data should have been posted to the remote URL. Go check this, and if it did not work properly, use curl_getinfo() function to see any errors that might have occurred.

print_r(curl_getinfo($curl_connection));

This line displays an array of information regarding the transfer. This must be used before closing the connection with curl_close();

You can also see number and description of the error by outputting curl_errno($curl_connection) and curl_error($curl_connection).

So let’s put everything together. Here is our code:


<?php

//create array of data to be posted
$post_data['firstName'] = 'Name';
$post_data['action'] = 'Register';

//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.domainname.com/target_url.php');

//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);

//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);

?>

Post Form data without using cURL

If your hosting server does not come with cURL installed (though this is rare as cURL is installed on most commercial hosting servers) and you also dont have access to server in order to install it, there are alternatives.

One of them is using PHP’s functions fsockopen() and fputs() to send properly formatted data to a remote server. Here is a sample of code that does just this:

//create array of data to be posted
$post_data['firstName'] = 'Name';
$post_data['action'] = 'Register';

//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);

//we also need to add a question mark at the beginning of the string
$post_string = '?' . $post_string;

//we are going to need the length of the data string
$data_length = strlen($post_string);

//let's open the connection
$connection = fsockopen('www.domainname.com', 80);

//sending the data
fputs($connection, "POST /target_url.php HTTP/1.1rn");
fputs($connection, "Host: www.domainname.com rn");
fputs($connection, "Content-Type: application/x-www-form-urlencodedrn");
fputs($connection, "Content-Length: $data_lengthrn");
fputs($connection, "Connection: closernrn");
fputs($connection, $post_string);

//closing the connection
fclose($fp);

?>

Posting data programmatically, absolutely invisible for your site visitors, can sometimes help you greatly improve usability and functionality of your site.

Source

  • Pingback: proxy server list | Digg hot tags

  • Pingback: open dns server | Digg hot tags

  • http://photoartsforum.com Ryan

    Thanks for the tips. The cURL saved me a lot of trial and error.

    One question. How would I go about getting the returned data from the fsockopen method? I’m running it and not getting any errors, but nothing is being inserted into the database like it should and I’d like to see if there’s an error somewhere.

  • http://www.blue2blond.nl Erwin

    @ Ryan

    You could use fgets to retrieve the returned data. See the examples at http://php.net/fsockopen (search for fgets on that page).

  • http://footballfreetv.com footballfreetv

    thanx man for this tutorial
    u really saved my a$$..

    thanx a bunch :)

  • Bob Jenkins

    What if the web page has more than one form on it, how do you instruct cURL to use a specific form on the page? (And the assumption is that there are the same fields in the forms, because I assume that if all the form field names are different, there’d be no issue.)

  • http://tareq.wedevs.com Tareq

    Thanks for these nice tute. I noticed this post many days ago and decided to read it later. Today i got the chance. This was very useful to me.

  • Prabhas

    I have a question..

    If I have two forms (identified by ‘name’ property) with similar input field names, then how to specify which form field to be populated?

  • Jayesh

    Really nice article…
    I have used this technique and solved a problem quickly, actually I was looking for such a technique to post data to another server.

    Thanks dude and keep it up.

  • Opsix

    I will like to know how i can automatically submit some data to a website form without visiting the website and then get the result in a variable
    the remote website is in javascript form but i need to use php to submit some data to it and return results to a php variable on my own site
    Any Help?
    Thanks

  • admin

    if the form is created with js, you can’t submit the form using cURL. however, you may do a trick. look the field names and action of the form. then make a php script that submits values to that action URL. then call the php script using your javascript (ajax call) as you can’t access the remote URL in javascript.

  • h3cker

    thx for the tut man.

    Regarding Javascript -> try this website http://www.megaupload.com/?c=login
    to submit logindetails. Could that be done?

    Actually my goal is to submit an upload being logged-in.
    thx for any share you can make regarding this my friend

  • http://www.99tutes.com shirish V

    Can we scrape the site generating content with Javascript?

  • The HungryCoder

    I guess YES, if you scrapper can handle javascript ;).

  • Amer

    Hi to all,

    I’m new in curl and I have a problem. I have a following code:

    $url = “registracija_1.php”;
    $params = “?kor_ime=neko”;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_POST,1);
    curl_setopt($ch, CURLOPT_POSTFIELDS,$params);
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

    $result=curl_exec ($ch);

    /*print_r(curl_getinfo($ch));
    echo curl_errno($chn) . ‘-‘ . curl_error($ch);*/

    curl_close ($ch);

    File registracija_1.php is on the same server (in the same folder) like the file which contains this code. But wen this file is loaded it shows me a black page, and don’t redirect me to registracija_1.php.

    What is a problem?
    Is user agent a required parameter?

    Thanks in advance…

  • The HungryCoder

    Hello,
    Try using absolute URL! and your parameters for CURLOPT_POSTFIELDS may not be correct! Please check http://php.net/manual/en/function.curl-setopt.php for example!

  • Ritu Goel

    Hi The Hungry Coder,

    Thank you for your effort for writing this post. Its very informative.

    Just a confusion as I am very new to cURL. I am trying to write a code in which i want to send a keyword to search box of another website and return if I get any positive result or not. Will this script of urs work? What changes do I need to make? Please help me! Thanks a lot!

  • Pingback: How to submit a form using PHP (cURL, fsockopen) | The HungryCoder

  • Mace

    Thanks for the tut, very clear and easy to follow, and worked great!
    For those asking how to grab data from a page, I use simple_html_dom (http://sourceforge.net/projects/simplehtmldom/)

    I put the curl data into it :

    $html = str_get_html($result);

    and then find all the input fields:

    foreach($html->find(‘input’) as $e){
    $input_class_array[].=$e->class;
    $input_name_array[].=$e->name;
    $input_value_array[].=$e->value;
    }

    or just the fields I need:

    foreach($html->find(‘textarea’) as $e)
    $text_area_key = $e->name;

    Then use the hungry coder’s method to put data in to those fields.

  • http://www.bluewaterinternet.com Bob

    I’m trying to post field data to a remote .asp page that posts to itself and then displays an answer in an input field on that same .asp page. I know the fields to use in your curl example code, and the correct url, but I don’t know how to get the resulting url page that displays (with the answer) after my remote post. Any help would be really appreciated.

  • http://www.bluewaterinternet.com Bob

    Thanks Mace,
    adding:
    include_once(‘simple_html_dom.php’); // from simplehtmldom, link above in Mace’s post
    $html = str_get_html($result);
    gave me the page content that displays after posting the form data. I was then able to parse through that with some other simplehtmldom functions and get the info I needed.

  • invincible

    is there anything we need to include for working curl?

  • :ZyLnT

    dead link :(