web-dev-qa-db-fra.com

PHP - Redirige et envoie des données via POST

J'ai une passerelle en ligne qui nécessite qu'un formulaire HTML soit soumis avec des champs cachés. Je dois le faire via un script PHP sans formulaire HTML (j'ai les données pour les champs cachés dans une base de données)

Pour ce faire, envoyez des données via GET:

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

Et faire cela en envoyant des données via POST?

46
Robinicks

Vous ne pouvez pas faire cela en utilisant PHP.

Comme d'autres l'ont déjà dit, vous pouvez utiliser cURL, mais le code PHP) devient le client plutôt que le navigateur.

Si vous devez utiliser POST, le seul moyen de le faire consiste à générer le formulaire rempli à l'aide de PHP) et à utiliser le hook window.onload pour appeler javascript afin de soumettre le formulaire.

C.

42
symcbean

voici l'échantillon de solution de contournement.

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

Une autre solution si vous souhaitez éviter un appel curl et que le navigateur redirige comme d'habitude et imiter un appel POST call:

enregistrer le message et faire une redirection temporaire:

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

Ensuite, vérifiez toujours la variable de session post_data:

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

Certains composants manquants, tels qu'Apache_request_headers () ne montreront pas un en-tête de contenu POST, etc.).

9
newms87

Cela impliquerait l’extension cURL PHP.

$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);
5
Matt

J'ai trouvé une solution meilleure et plus ordonnée alors j'ai pensé que je devrais la partager:

Utilisez la session:

$_SESSION['POST'] = $_POST;

et pour la demande d’en-tête de redirection, vous devez utiliser:

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

307 est le htttp_response_code vous pouvez utiliser pour la demande de redirection avec les valeurs soumises POST.

4
MajidJafari
/**
 * 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");
    }
}
4
Eduardo Cuomo

Utilisez curl pour cela. Google pour "curl php post" et vous trouverez ceci: http://www.askapache.com/htaccess/sending-post-form-data-with-php-curl.html .

Notez que vous pouvez également utiliser un tableau pour l'option CURLOPT_POSTFIELDS. De php.net docs:

Les données complètes à publier dans une opération HTTP "POST". Pour poster un fichier, ajoutez un @ à un nom de fichier et utilisez le chemin complet. Cela peut être passé sous forme de chaîne codée par url, telle que 'para1 = val1 & para2 = val2 & ...' ou sous forme de tableau avec le nom du champ comme clé et les données du champ comme valeur. Si value est un tableau, l'en-tête Content-Type sera défini sur multipart/form-data.

2
svens

Je crains que vous n'ayez besoin de CURL pour cette tâche. Beau moyen facile de le faire ici: http://davidwalsh.name/execute-http-post-php-curl

J'espère que ça t'as aidé

1
Glyn Mooney

Vous devez ouvrir un socket sur le site avec fsockopen et simuler une HTTP-Post-Request. Google vous montrera de nombreux extraits comment simuler la demande.

1
Tobias P.

Sinon, définir une variable de session avant la redirection et le tester dans l'URL de destination peut résoudre ce problème pour moi.

Oui, vous pouvez le faire dans PHP par exemple, dans

Silex ou Symfony3

en utilisant la sous-demande

$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
R Picheta

Une solution de contournement qui fonctionne parfaitement:

Dans la page source, commencez à ouvrir une session et attribuez autant de valeurs que vous le souhaitez. Ensuite, faites la relocalisation avec "header":

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

Et puis, dans la page 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>

Pas besoin de Javascript ni de JQuery .. Bonne chance!

0
PVE

Un ancien post mais voici comment je l'ai géré. En utilisant la méthode 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
Adam Benoit

J'ai utilisé le code suivant pour capturer POST les données soumises à partir de form.php, puis les concaténer sur une URL pour les renvoyer RETOUR au formulaire pour les corrections de validation. Fonctionne comme un charme, et dans effect convertit les données POST en données GET.

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

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