51

I have an online gateway which requires an HTML form to be submitted with hidden fields. I need to do this via a PHP script without any HTML forms (I have the data for the hidden fields in a DB)

To do this sending data via GET:

header('Location: http://www.provider.com/process.jsp?id=12345&name=John');

And to do this sending data via POST?

pnuts
  • 58,317
  • 11
  • 87
  • 139
Robin Rodricks
  • 110,798
  • 141
  • 398
  • 607

14 Answers14

46

You can't do this using PHP.

As others have said, you could use cURL - but then the PHP code becomes the client rather than the browser.

If you must use POST, then the only way to do it would be to generate the populated form using PHP and use the window.onload hook to call javascript to submit the form.

Dharman
  • 30,962
  • 25
  • 85
  • 135
symcbean
  • 47,736
  • 6
  • 59
  • 94
  • 3
    Well thats weird that cURL isnt the solution as I have used it myself to do exactly this. But I guess your solution works as well. – Arto Uusikangas Jun 15 '10 at 12:52
  • 2
    You can use jQuery $.post method. In this case you can choose between options to stay on this site or redirect when submited. – Ervin Nov 27 '12 at 10:24
  • Yes, its possible to proxy the request and convert it into a POST using PHP and curl - but that implies that the receiving end is susceptible to CSRF and/or is not applying a session based controls over the request (you can fudge some of this, but not all in the parameters passed to curl) – symcbean Oct 26 '15 at 11:06
  • 1) there was *very* limited supprot for 308 redirects in 2015 2) a permanent redirect is almost always the wrong answer to any problem – symcbean Feb 22 '19 at 11:29
  • http://mentaljetsam.wordpress.com/2008/06/02/using-javascript-to-post-data-between-pages/ – Stefan Jun 22 '20 at 20:40
39

here is the workaround sample.

function redirect_post($url, array $data)
{
    ?>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <script type="text/javascript">
            function closethisasap() {
                document.forms["redirectpost"].submit();
            }
        </script>
    </head>
    <body onload="closethisasap();">
    <form name="redirectpost" method="post" action="<? echo $url; ?>">
        <?php
        if ( !is_null($data) ) {
            foreach ($data as $k => $v) {
                echo '<input type="hidden" name="' . $k . '" value="' . $v . '"> ';
            }
        }
        ?>
    </form>
    </body>
    </html>
    <?php
    exit;
}
rezashamdani
  • 577
  • 6
  • 11
12

A better and neater solution would be to use $_SESSION:

Using the session:

$_SESSION['POST'] = $_POST;

and for the redirect header request use:

header('Location: http://www.provider.com/process.jsp?id=12345&name=John', true, 307;)

307 is the http_response_code you can use for the redirection request with submitted POST values.

Dipanshu Mahla
  • 152
  • 1
  • 16
MajidJafari
  • 1,076
  • 11
  • 15
11

Another solution if you would like to avoid a curl call and have the browser redirect like normal and mimic a POST call:

save the post and do a temporary redirect:

function post_redirect($url) {
    $_SESSION['post_data'] = $_POST;
    header('Location: ' . $url);
}

Then always check for the session variable post_data:

if (isset($_SESSION['post_data'])) {
    $_POST = $_SESSION['post_data'];
    $_SERVER['REQUEST_METHOD'] = 'POST';
    unset($_SESSION['post_data']);
}

There will be some missing components such as the apache_request_headers() will not show a POST Content header, etc..

newms87
  • 834
  • 1
  • 10
  • 23
7

It would involve the cURL PHP extension.

$ch = curl_init('http://www.provider.com/process.jsp');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "id=12345&name=John");
curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1);  // RETURN THE CONTENTS OF THE CALL
$resp = curl_exec($ch);
Matt
  • 3,778
  • 9
  • 35
  • 36
5
/**
 * Redirect with POST data.
 *
 * @param string $url URL.
 * @param array $post_data POST data. Example: array('foo' => 'var', 'id' => 123)
 * @param array $headers Optional. Extra headers to send.
 */
public function redirect_post($url, array $data, array $headers = null) {
    $params = array(
        'http' => array(
            'method' => 'POST',
            'content' => http_build_query($data)
        )
    );
    if (!is_null($headers)) {
        $params['http']['header'] = '';
        foreach ($headers as $k => $v) {
            $params['http']['header'] .= "$k: $v\n";
        }
    }
    $ctx = stream_context_create($params);
    $fp = @fopen($url, 'rb', false, $ctx);
    if ($fp) {
        echo @stream_get_contents($fp);
        die();
    } else {
        // Error
        throw new Exception("Error loading '$url', $php_errormsg");
    }
}
Eduardo Cuomo
  • 17,828
  • 6
  • 117
  • 94
  • I'm new to PHP. Is there any way to change the URL with it? This function doesn't change the URL, but redirects. I'm leaving the `$headers` as `null` (should I be?). – Michael Yaworski Jul 19 '15 at 02:14
2

Use curl for this. Google for "curl php post" and you'll find this: http://www.askapache.com/htaccess/sending-post-form-data-with-php-curl.html.

Note that you could also use an array for the CURLOPT_POSTFIELDS option. From php.net docs:

The full data to post in a HTTP "POST" operation. To post a file, prepend a filename with @ and use the full path. This can either be passed as a urlencoded string like 'para1=val1&para2=val2&...' or as an array with the field name as key and field data as value. If value is an array, the Content-Type header will be set to multipart/form-data.

svens
  • 11,438
  • 6
  • 36
  • 55
1

Alternatively, setting a session variable before the redirect and test it in the destination url, can solve this problem for me.

1

Your going to need CURL for that task I'm afraid. Nice easy way to do it here: http://davidwalsh.name/execute-http-post-php-curl

Hope that helps

1

You have to open a socket to the site with fsockopen and simulate a HTTP-Post-Request. Google will show you many snippets how to simulate the request.

rink.attendant.6
  • 44,500
  • 61
  • 101
  • 156
Tobias P.
  • 4,537
  • 2
  • 29
  • 36
0

I used the following code to capture POST data that was submitted from form.php and then concatenate it onto a URL to send it BACK to the form for validation corrections. Works like a charm, and in effect converts POST data into GET data.

foreach($_POST as $key => $value) {
   $urlArray[] =  $key."=".$value;  
}
$urlString = implode("&", $urlArray);

echo "Please <a href='form.php?".$urlString."'>go back</a>";
Michael
  • 1
  • 2
0

Yes, you can do this in PHP e.g. in

Silex or Symfony3

using subrequest

$postParams = array(
    'email' => $request->get('email'),
    'agree_terms' => $request->get('agree_terms'),
);

$subRequest = Request::create('/register', 'POST', $postParams);
return $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false);
Yury Fedorov
  • 14,508
  • 6
  • 50
  • 66
R Picheta
  • 630
  • 9
  • 16
0

An old post but here is how I handled it. Using newms87's method:

if($action == "redemption")
{
    if($redemptionId != "")
    {
        $results = json_decode($rewards->redeemPoints($redemptionId));

        if($results->success == true)
        {
            $redirectLocation = $GLOBALS['BASE_URL'] . 'rewards.phtml?a=redemptionComplete';
            // put results in session and redirect back to same page passing an action paraameter
            $_SESSION['post_data'] = json_encode($results);
            header("Location:" . $redirectLocation);
            exit();
        }
    }
}
elseif($action == "redemptionComplete")
{
    // if data is in session pull it and unset it.
    if(isset($_SESSION['post_data']))
    {
        $results = json_decode($_SESSION['post_data']);
        unset($_SESSION['post_data']);
    }
    // if you got here, you completed the redemption and reloaded the confirmation page. So redirect back to rewards.phtml page.
    else
    {
        $redirectLocation = $GLOBALS['BASE_URL'] . 'rewards.phtml';
        header("Location:" . $redirectLocation);
    }
}
Adam Benoit
  • 376
  • 1
  • 13
0

A workaround wich works perfectly :

In the source page,, start opening a session and assign as many values as you might want. Then do the relocation with "header" :

<!DOCTYPE html>
<html>
   <head>
       <?php
           session_start();
           $_SESSION['val1'] = val1;
           ...
           $_SESSION['valn'] = valn;
           header('Location: http//Page-to-redirect-to');
       ?>
   </head>
</html>

And then, in the targe page :

<!DOCTYPE html>
<?php
    session_start();
?>
<html>
    ...
    <body>
        <?php
            if (isset($_SESSION['val1']) && ... && isset($_SESSION['valn'])) {
                YOUR CODE HERE based on $_SESSION['val1']...$_SESSION['valn'] values
            }
        ?>
    </body>
</html>

No need of Javascript nor JQuery.. Good luck !

PVE
  • 1
  • 1