PHP – Redirecting a form with POST variables.

On more than one occasion, I’ve come across novice PHP developers looking for ways to redirect the user and their submitted form variables to an external website.

More often than not, they’ll ask if they can somehow attach POST variables to a header redirect.

After this fails and they finally realize that another solution is needed, they’ll usually attempt to use an HTTP library such as cURL.

Unfortunately, cURL will not help in this case.

Hold up!

If the site in question has an API, then you should definitely access that instead of playing around with redirects.

If they do have an API, then you should be able to interact with it using cURL.

The solutions below are for websites that willingly accept POST data from users that are entering their site for the first time. For example, PayPal and some of the other online merchants.

If the site does not officially accept such requests and you’re trying to glue all of this functionality together, then don’t be surprised to find out that your application suddenly breaks overnight because a form field was renamed or they added a captcha.

If the site currently requires a captcha before the form submission is accepted, then you will be out of luck. That is a completely different “issue” that is not covered here.

cURL.

In this case, the problem with cURL is that the request is sent via the server.

In other words, the request will not come from the user’s browser.

Therefore, the user’s browser and the external website will be completely oblivious to one another.

As far as they’re concerned, they’ve never met each other before. This is because cURL is acting as a middleman between the user and the external website.

It grabs the data from the user before forwarding it on. This means that if you forward the POST data via cURL, the website in question will fail to recognize it as a request from your user.

This can be a major issue if your user needs to carry out further actions after the form is submitted.

For example, if the user needs to enter their credit card details or click on a confirmation button, then using cURL is going to be cumbersome at best.

If the site relies on JavaScript or some other form of client-side processing, then using cURL is going to become even more complicated as cURL cannot process JavaScript or interact with browser plugins.

“I don’t really care about redirecting the user. I just want to forward the POST data.”

If you’re OK with not redirecting the user to the website in question, then a once-off cURL request might be the perfect solution for you.

If the site accepts and accommodates POST requests without forcing the user to jump through hoops, then you could forward the data on like so:

//The names of the POST variables that we want to send
//to the external website.
$postVars = array('name', 'email', 'dob');

//An array to hold the data that we'll end up sending. 
//Empty by default.
$postData = array();

//Attemp to find the POST variables that we want to send.
foreach($postVars as $name){
    if(isset($_POST[$name])){
        $postData[$name] = $_POST[$name];
    }
}

//Setup cURL
$ch = curl_init();

//The site we'll be sending the POST data to.
curl_setopt($ch, CURLOPT_URL, "http://example.com");

//Tell cURL that we want to send a POST request.
curl_setopt($ch, CURLOPT_POST, 1);

//Attach our POST data.
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);

//Tell cURL that we want to receive the response that the site
//gives us after it receives our request.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

//Finally, send the request.
$response = curl_exec($ch);

//Close the cURL session
curl_close($ch);

//Do whatever you want to do with the output.
echo $response;

You can then parse the $response variable and inform the user whether they were successful or not.

I need to make sure that the user is redirected.

In certain cases, you will need to redirect the user to the site in question.

With online merchants such as PayPal, this is a must as the user will be prompted to enter their payment details once they’ve landed on the site.

If you don’t need to process the form data before it is sent, then simply adding the external site’s URL to your form’s action attribute should do the trick:

<form action="http://example.com" method="post">
    <input type="text" name="name">
    <input type="text" name="email">
    <input type="text" name="etc">
    <input type="submit" name="submission_button">
</form>

The benefit of this is that you don’t even need to redirect the user. They just submit the form and the data goes directly to the site that is waiting to accept it.

I need to process the form data before the user leaves.

If you need to process the form data before the user leaves your website, then you will need to take the following steps:

  1. Process the user’s form submission.
  2. Bring the user to another page that has an “invisible form”. This “form” should be created using hidden fields. The fields should contain data from the form that they previously submitted.
  3. Automatically submit the “invisible form” using JavaScript. That or you can prompt the user to submit it again by asking them to confirm their details.

The “invisible form” might look something like this:

<form id="my_form" action="http://example.com" method="post">
    <input type="hidden" name="name" value="<?php echo htmlspecialchars($name); ?>">
    <input type="hidden" name="email" value="<?php echo htmlspecialchars($email); ?>">
    <input type="hidden" name="etc" value="<?php echo htmlspecialchars($etc); ?>">
</form>

<script type="text/javascript">
    //Our form submission function.
    function submitForm() {
        document.getElementById('my_form').submit();
    }
    //Call the function submitForm() as soon as the page has loaded.
    window.onload = submitForm;
</script>

The problem with the code above is that the user needs to have JavaScript enabled for it to work. As a fail-safe, you could add a visible submit button to the form. One that says something such as “Click here if the site is taking too long to redirect!” or “Confirm Submission”:

<?php
$name = isset($_POST['name']) ? $_POST['name'] : null;
$email = isset($_POST['email']) ? $_POST['email'] : null;
$etc = isset($_POST['etc']) ? $_POST['etc'] : null;
?>

<form id="my_form" action="http://example.com" method="post">
    <input type="hidden" name="name" value="<?php echo htmlspecialchars($name); ?>">
    <input type="hidden" name="email" value="<?php echo htmlspecialchars($email); ?>">
    <input type="hidden" name="etc" value="<?php echo htmlspecialchars($etc); ?>">
    <input type="submit" name="submission_button" value="Click here if the site is taking too long to redirect!">
</form>

<script type="text/javascript">
    function submitForm() {
        document.getElementById('my_form').submit();
    }
    window.onload = submitForm;
</script>