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?

14 Answers 14

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.

Sign up to request clarification or add additional context in comments.

5 Comments

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.
You can use jQuery $.post method. In this case you can choose between options to stay on this site or redirect when submited.
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)
1) there was very limited supprot for 308 redirects in 2015 2) a permanent redirect is almost always the wrong answer to any problem
38

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; } 

6 Comments

Its a "dirty" solution, but definitely works! I made a similar function but with an explicit echo instead of closing and reopening the <? ?> tags
I love this kind of dirty stuff. php tags may need to be set as <?php
@DiegoDD: do you have any code / gist so that I can copy?
Dirty but Good solution
|
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.

Comments

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..

Comments

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

3 Comments

Hey Matt,This is not possible with CURL. By curl we wont be redirected.
@rahul Does curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); not solve this issue?
From my experience CURLOPT_FOLLOWLOCATION doesn't work in a Laravel controller.
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"); } } 

1 Comment

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?).
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.

Comments

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

Comments

1

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

Comments

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.

Comments

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>"; 

2 Comments

Unfortunatly this is not what was asked. He wants to POST via a redirect, not convert POST to GET.
Besides, if you want to achieve this you can also use PHP's native function http_build_query().
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); } } 

Comments

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

Comments

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 !

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.