web-dev-qa-db-fra.com

Comment faites-vous POST sur une page en utilisant la fonction PHP header ()?

J'ai trouvé le code suivant sur ici qui, je pense, fait ce que je veux, mais cela ne fonctionne pas:

$Host = "www.example.com";
$path = "/path/to/script.php";
$data = "data1=value1&data2=value2";
$data = urlencode($data);

header("POST $path HTTP/1.1\r\n");
header("Host: $Host\r\n");
header("Content-type: application/x-www-form-urlencoded\r\n");
header("Content-length: " . strlen($data) . "\r\n");
header("Connection: close\r\n\r\n");
header($data);

Je cherche à publier des données de formulaire sans envoyer les utilisateurs vers une page intermédiaire, puis à l'aide de JavaScript pour les rediriger. Je ne veux pas non plus utiliser GET, il n'est donc pas aussi facile d'utiliser le bouton de retour.

Y a-t-il un problème avec ce code? Ou existe-t-il une meilleure méthode?

Edit Je pensais à ce que ferait la fonction d'en-tête. Je pensais que je pourrais demander au navigateur de publier sur le serveur avec les données, mais ce n'est pas ce qu'il est censé faire. Au lieu de cela, j'ai trouvé un moyen dans mon code pour éviter la nécessité d'une publication (ne pas casser et simplement continuer sur le prochain cas dans le commutateur).

20
Darryl Hein

La fonction d'en-tête est utilisée pour renvoyer les en-têtes de réponse HTTP à l'utilisateur (c'est-à-dire que vous ne pouvez pas l'utiliser pour créer des en-têtes de demande.

Puis-je demander pourquoi faites-vous cela? Pourquoi simuler une demande POST alors que vous pouvez juste là et ensuite agir sur les données? Je suppose bien sûr que script.php réside sur votre serveur.

Pour créer une POST, ouvrez une connexion TCP à l'hôte à l'aide de fsockopen (), puis utilisez fwrite () sur le gestionnaire renvoyé par fsockopen ( ) avec les mêmes valeurs que celles utilisées dans les fonctions d'en-tête de l'OP. Vous pouvez également utiliser cURL.

12
Salaryman

La réponse à cette question est très nécessaire aujourd'hui car tout le monde ne veut pas utiliser cURL pour consommer des services Web. PHP permet cela en utilisant le code suivant

function get_info()
{
    $post_data = array(
        'test' => 'foobar',
        'okay' => 'yes',
        'number' => 2
    );

    // Send a request to example.com
    $result = $this->post_request('http://www.example.com/', $post_data);

    if ($result['status'] == 'ok'){

        // Print headers
        echo $result['header'];

        echo '<hr />';

        // print the result of the whole request:
        echo $result['content'];

    }
    else {
        echo 'A error occured: ' . $result['error'];
    }

}

function post_request($url, $data, $referer='') {

    // Convert the data array into URL Parameters like a=b&foo=bar etc.
    $data = http_build_query($data);

    // parse the given URL
    $url = parse_url($url);

    if ($url['scheme'] != 'http') {
        die('Error: Only HTTP request are supported !');
    }

    // extract Host and path:
    $Host = $url['Host'];
    $path = $url['path'];

    // open a socket connection on port 80 - timeout: 30 sec
    $fp = fsockopen($Host, 80, $errno, $errstr, 30);

    if ($fp){

        // send the request headers:
        fputs($fp, "POST $path HTTP/1.1\r\n");
        fputs($fp, "Host: $Host\r\n");

        if ($referer != '')
            fputs($fp, "Referer: $referer\r\n");

        fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
        fputs($fp, "Content-length: ". strlen($data) ."\r\n");
        fputs($fp, "Connection: close\r\n\r\n");
        fputs($fp, $data);

        $result = '';
        while(!feof($fp)) {
            // receive the results of the request
            $result .= fgets($fp, 128);
        }
    }
    else {
        return array(
            'status' => 'err',
            'error' => "$errstr ($errno)"
        );
    }

    // close the socket connection:
    fclose($fp);

    // split the result header from the content
    $result = explode("\r\n\r\n", $result, 2);

    $header = isset($result[0]) ? $result[0] : '';
    $content = isset($result[1]) ? $result[1] : '';

    // return as structured array:
    return array(
        'status' => 'ok',
        'header' => $header,
        'content' => $content);

}
4
Carl McDade

En plus de ce que Salaryman a dit, jetez un œil aux classes dans PEAR , il y a des classes de requêtes HTTP que vous pouvez utiliser même si vous n'avez pas le Extension cURL installée dans votre distribution PHP.

2
cruizer

Il y a une bonne classe qui fait ce que vous voulez. Il peut être téléchargé sur: http://sourceforge.net/projects/snoopy/

1
creatvepro