2010-06-15 21 views
40

Ho un gateway online che richiede un modulo HTML da inviare con campi nascosti. Ho bisogno di fare questo tramite uno script PHP senza moduli HTML (ho i dati per i campi nascosti in un DB)PHP - Reindirizzare e inviare dati tramite POST

Per fare questo l'invio dei dati tramite GET:

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

E per fare questo inviando dati via POST?

risposta

39

Non si può fare questo usando PHP.

Come altri hanno già detto, è possibile utilizzare cURL, ma il codice PHP diventa il client anziché il browser.

Se è necessario utilizzare POST, l'unico modo per farlo sarebbe generare il modulo popolato utilizzando PHP e utilizzare il hook window.onload per chiamare javascript per inviare il modulo.

C.

+3

Beh, è ​​strano che CURL non sia la soluzione perché l'ho usato io stesso per fare esattamente questo. Ma immagino che anche la tua soluzione funzioni. –

+0

È possibile utilizzare il metodo $ .post di jQuery. In questo caso puoi scegliere tra le opzioni per rimanere su questo sito o il reindirizzamento quando inviato. – Ervin

+0

Sì, è possibile eseguire il proxy della richiesta e convertirlo in un POST utilizzando PHP e curl, ma ciò implica che il destinatario è suscettibile a CSRF e/o non sta applicando un controllo basato sulla sessione sulla richiesta (è possibile fondere alcuni dei questo, ma non tutti i parametri passati al ricciolo) – symcbean

1

Utilizzare l'arricciatura per questo. Google per "curl php post" e troverai questo: http://www.askapache.com/htaccess/sending-post-form-data-with-php-curl.html.

Si noti che è anche possibile utilizzare una matrice per l'opzione CURLOPT_POSTFIELDS. Da documenti php.net:

I dati completi da inviare in un'operazione HTTP "POST". Per pubblicare un file, anteporre un nome file con @ e utilizzare il percorso completo. Questo può essere passato come una stringa urlencoded come 'para1 = val1 & para2 = val2 & ...' o come una matrice con il nome del campo come chiave e dati del campo come valore. Se value è un array, l'intestazione Content-Type sarà impostata su multipart/form-data.

4

Coinvolgerebbe l'estensione PHP cURL.

$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); 
+1

Hey Matt, Questo non è possibile con CURL. Con il ricciolo non saremo reindirizzati. – rahul

1

è necessario aprire un socket al sito con fsockopen e simulare un HTTP-Post-Request. Google ti mostrerà molti snippet come simulare la richiesta.

26

qui è l'esempio di soluzione.

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

È una soluzione "sporca", ma sicuramente funziona! Ho fatto una funzione simile ma con un esplicito 'echo' invece di chiudere e riaprire i tag' ' – DiegoDD

+0

Amo questo genere di cose sporche. i tag php potrebbero dover essere impostati come Kemal

+0

@DiegoDD: hai qualche codice/gist da poter copiare? – Hiep

0

ho usato il seguente codice per acquisire i dati POST che è stata presentata da form.php e poi concatenare è su un URL per inviare di nuovo al modulo per le correzioni di convalida. Funziona come un incantesimo e in effetti converte i dati POST in dati GET.

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

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

Sfortunatamente questo non è quello che è stato chiesto. Vuole effettuare il POST tramite un reindirizzamento, non convertire POST in GET. – TimWolla

+1

Inoltre, se si desidera ottenere ciò, è possibile utilizzare anche la funzione nativa di PHP 'http_build_query()'. – Ben

2
/** 
* 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"); 
    } 
} 
+0

Sono nuovo di PHP.C'è un modo per cambiare l'URL con esso? Questa funzione non cambia l'URL, ma reindirizza. Sto lasciando il '$ headers' come' null' (dovrei essere?). –

8

Un'altra soluzione se si desidera evitare una chiamata curl e avere il browser redirect come normale e simulare una chiamata POST:

salvare la posta e fare un redirect temporanea:

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

Poi sempre controllare per la variabile di sessione post_data:

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

Ci saranno alcuni componenti mancanti come le apache_request_headers() non mostrerà un'intestazione Content POST, ecc ..

+0

Grazie per la soluzione sporca più pulita. – Gregzenegair

1

In alternativa, impostando una variabile di sessione prima che il reindirizzamento e testarlo nella URL di destinazione, in grado di risolvere questo problema per me.

0

Sì, è possibile farlo in PHP, ad es. in

Silex o Symfony3

utilizzando sotto richiesta

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

Un vecchio post, ma qui è come ho gestito esso. Usando il metodo di newms87:

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

Un Quale soluzione funziona perfettamente:

Nella pagina di origine ,, avviare l'apertura di una sessione e assegnare tanti valori, come si potrebbe desiderare. poi fare il trasferimento con il "colpo di testa":

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

E poi, nella pagina targe:

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

Non c'è bisogno di Javascript JQuery né .. Buona fortuna!