web-dev-qa-db-fra.com

Comment puis-je envoyer un POST demande avec PHP?

En fait, je veux lire le contenu qui suit la requête de recherche, une fois celle-ci terminée. Le problème est que l'URL n'accepte que les méthodes POST et ne prend aucune mesure avec la méthode GET ...

Je dois lire tout le contenu à l'aide de domdocument ou file_get_contents(). Existe-t-il une méthode qui me permette d’envoyer des paramètres avec la méthode POST puis de lire le contenu via PHP?

573
Fred Tanrikut

Méthode sans CURL avec PHP5:

$url = 'http://server.com/path';
$data = array('key1' => 'value1', 'key2' => 'value2');

// use key 'http' even if you send the request to https://...
$options = array(
    'http' => array(
        'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
        'method'  => 'POST',
        'content' => http_build_query($data)
    )
);
$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === FALSE) { /* Handle error */ }

var_dump($result);

Consultez le manuel PHP pour plus d'informations sur la méthode et sur l'ajout d'en-têtes, par exemple:

1128
dbau

Vous pouvez utiliser cURL:

<?php
//The url you wish to send the POST request to
$url = $file_name;

//The data you want to send via POST
$fields = [
    '__VIEWSTATE '      => $state,
    '__EVENTVALIDATION' => $valid,
    'btnSubmit'         => 'Submit'
];

//url-ify the data for the POST
$fields_string = http_build_query($fields);

//open connection
$ch = curl_init();

//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);

//So that curl_exec returns the contents of the cURL; rather than echoing it
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true); 

//execute post
$result = curl_exec($ch);
echo $result;
?>
86
Fred Tanrikut

J'utilise la fonction suivante pour publier des données à l'aide de curl. $ data est un tableau de champs à publier (sera correctement codé avec http_build_query). Les données sont codées à l'aide de l'application/x-www-form-urlencoded.

function httpPost($url, $data)
{
    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($curl);
    curl_close($curl);
    return $response;
}

@Edward mentionne que http_build_query peut être omis car curl encodera correctement le tableau transmis au paramètre CURLOPT_POSTFIELDS, mais sachez que dans ce cas, les données seront codées à l'aide de multipart/form-data.

J'utilise cette fonction avec des API qui s'attendent à ce que les données soient codées à l'aide de application/x-www-form-urlencoded. C'est pourquoi j'utilise http_build_query ().

53
Dima L.

Je vous recommande d'utiliser le paquet open-source guzzle , qui est entièrement testé et utilise les pratiques de codage les plus récentes.

Installer Guzzle

Accédez à la ligne de commande du dossier de votre projet et entrez la commande suivante (en supposant que le gestionnaire de paquets composer est déjà installé). Si vous avez besoin d’aide pour installer Composer, vous devriez jeter un coup d’œil ici .

php composer.phar require guzzlehttp/guzzle

Utilisation de Guzzle pour envoyer une demande POST

L'utilisation de Guzzle est très simple car elle utilise une API orientée objet légère:

// Initialize Guzzle client
$client = new GuzzleHttp\Client();

// Create a POST request
$response = $client->request(
    'POST',
    'http://example.org/',
    [
        'form_params' => [
            'key1' => 'value1',
            'key2' => 'value2'
        ]
    ]
);

// Parse the response object, e.g. read the headers, body, etc.
$headers = $response->getHeaders();
$body = $response->getBody();

// Output headers and body for debugging purposes
var_dump($headers, $body);
36
Andreas

Il y a une autre méthode CURL si vous allez dans cette direction.

C'est assez simple une fois que vous avez compris le fonctionnement de l'extension PHP curl, qui combine divers indicateurs avec des appels setopt (). Dans cet exemple, j'ai une variable $ xml contenant le code XML que j'ai préparé à envoyer. Je vais publier le contenu de cette méthode de test, par exemple.

$url = 'http://api.example.com/services/xmlrpc/';
$ch = curl_init($url);

curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);
//process $response

Nous avons d’abord initialisé la connexion, puis nous avons défini quelques options en utilisant setopt (). Ils indiquent PHP que nous faisons une demande de publication et que nous envoyons des données avec, fournissant les données. L'indicateur CURLOPT_RETURNTRANSFER indique à curl de nous donner le résultat en tant que valeur de retour de curl_exec plutôt que de le générer. Ensuite, nous passons l'appel et fermons la connexion - le résultat est dans $ réponse.

23
Josip Ivic

Si, par hasard, vous utilisez Wordpress pour développer votre application (c'est en fait un moyen pratique d'obtenir une autorisation, des pages d'informations, etc. même pour des choses très simples), vous pouvez utiliser l'extrait suivant:

$response = wp_remote_post( $url, array('body' => $parameters));

if ( is_wp_error( $response ) ) {
    // $response->get_error_message()
} else {
    // $response['body']
}

Il utilise différentes méthodes pour créer la demande HTTP réelle, en fonction de ce qui est disponible sur le serveur Web. Pour plus de détails, voir la Documentation sur l'API HTTP .

Si vous ne souhaitez pas développer un thème ou un plug-in personnalisé pour démarrer le moteur Wordpress, vous pouvez simplement procéder comme suit dans un fichier PHP isolé dans la racine wordpress:

require_once( dirname(__FILE__) . '/wp-load.php' );

// ... your code

Il ne montrera aucun thème ni n'émettra de code HTML, il suffit de pirater les API Wordpress!

18
user3638471

J'aimerais ajouter quelques réflexions à propos de la réponse de Fred Tanrikut à la boucle. Je sais que la plupart d’entre eux sont déjà écrits dans les réponses ci-dessus, mais je pense que c’est une bonne idée de montrer une réponse qui les inclut tous ensemble. 

Voici la classe que j'ai écrite pour faire des requêtes HTTP-GET/POST/PUT/DELETE basées sur curl, concernant à peu près le corps de la réponse:

class HTTPRequester {
    /**
     * @description Make HTTP-GET call
     * @param       $url
     * @param       array $params
     * @return      HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPGet($url, array $params) {
        $query = http_build_query($params); 
        $ch    = curl_init($url.'?'.$query);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, false);
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
    }
    /**
     * @description Make HTTP-POST call
     * @param       $url
     * @param       array $params
     * @return      HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPPost($url, array $params) {
        $query = http_build_query($params);
        $ch    = curl_init();
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
    }
    /**
     * @description Make HTTP-PUT call
     * @param       $url
     * @param       array $params
     * @return      HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPPut($url, array $params) {
        $query = \http_build_query($params);
        $ch    = \curl_init();
        \curl_setopt($ch, \CURLOPT_RETURNTRANSFER, true);
        \curl_setopt($ch, \CURLOPT_HEADER, false);
        \curl_setopt($ch, \CURLOPT_URL, $url);
        \curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, 'PUT');
        \curl_setopt($ch, \CURLOPT_POSTFIELDS, $query);
        $response = \curl_exec($ch);
        \curl_close($ch);
        return $response;
    }
    /**
     * @category Make HTTP-DELETE call
     * @param    $url
     * @param    array $params
     * @return   HTTP-Response body or an empty string if the request fails or is empty
     */
    public static function HTTPDelete($url, array $params) {
        $query = \http_build_query($params);
        $ch    = \curl_init();
        \curl_setopt($ch, \CURLOPT_RETURNTRANSFER, true);
        \curl_setopt($ch, \CURLOPT_HEADER, false);
        \curl_setopt($ch, \CURLOPT_URL, $url);
        \curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, 'DELETE');
        \curl_setopt($ch, \CURLOPT_POSTFIELDS, $query);
        $response = \curl_exec($ch);
        \curl_close($ch);
        return $response;
    }
}

Améliorations

  • Utiliser http_build_query pour extraire la chaîne de requête d’un tableau de requêtes (vous pouvez également utiliser le tableau lui-même, consultez donc: http://php.net/manual/en/function.curl-setopt.php )
  • Renvoyer la réponse au lieu de la répercuter. Pour éviter ce problème, supprimez la ligne curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, true); Après cela, la valeur renvoyée est un booléen (true = la requête a abouti, sinon une erreur est survenue) et la réponse est renvoyée. Voir: http://php.net/fr/manual/function.curl-exec.php
  • Nettoyez la fermeture de session et la suppression du gestionnaire curl en utilisant curl_close. Voir: http://php.net/manual/en/function.curl-close.php
  • Utiliser des valeurs booléennes pour la fonction curl_setopt au lieu d'utiliser n'importe quel nombre (je sais que tout nombre non égal à zéro est également considéré comme vrai, mais l'utilisation de true génère un code plus lisible, mais ce n'est que mon opinion)
  • Possibilité d'effectuer des appels HTTP-PUT/DELETE (utile pour les tests de service RESTful)

Exemple d'utilisation

GET

$response = HTTPRequester::HTTPGet("http://localhost/service/foobar.php", array("getParam" => "foobar"));

POST

$response = HTTPRequester::HTTPPost("http://localhost/service/foobar.php", array("postParam" => "foobar"));

METTRE

$response = HTTPRequester::HTTPPut("http://localhost/service/foobar.php", array("putParam" => "foobar"));

EFFACER

$response = HTTPRequester::HTTPDelete("http://localhost/service/foobar.php", array("deleteParam" => "foobar"));

Essai

Vous pouvez également faire des tests de service intéressants en utilisant cette classe simple.

class HTTPRequesterCase extends TestCase {
    /**
     * @description test static method HTTPGet
     */
    public function testHTTPGet() {
        $requestArr = array("getLicenses" => 1);
        $url        = "http://localhost/project/req/licenseService.php";
        $this->assertEquals(HTTPRequester::HTTPGet($url, $requestArr), '[{"error":false,"val":["NONE","AGPL","GPLv3"]}]');
    }
    /**
     * @description test static method HTTPPost
     */
    public function testHTTPPost() {
        $requestArr = array("addPerson" => array("foo", "bar"));
        $url        = "http://localhost/project/req/personService.php";
        $this->assertEquals(HTTPRequester::HTTPPost($url, $requestArr), '[{"error":false}]');
    }
    /**
     * @description test static method HTTPPut
     */
    public function testHTTPPut() {
        $requestArr = array("updatePerson" => array("foo", "bar"));
        $url        = "http://localhost/project/req/personService.php";
        $this->assertEquals(HTTPRequester::HTTPPut($url, $requestArr), '[{"error":false}]');
    }
    /**
     * @description test static method HTTPDelete
     */
    public function testHTTPDelete() {
        $requestArr = array("deletePerson" => array("foo", "bar"));
        $url        = "http://localhost/project/req/personService.php";
        $this->assertEquals(HTTPRequester::HTTPDelete($url, $requestArr), '[{"error":false}]');
    }
}
16
mwatzer

Une autre alternative de la méthode curl-less ci-dessus consiste à utiliser les fonctions natives flux:

  • stream_context_create() :

    Crée et retourne un contexte de flux avec les options fournies dans options preset.

  • stream_get_contents() :

    Identique à file_get_contents() , sauf que stream_get_contents()opère sur une ressource stream déjà ouverte et renvoie le contenu restant dans une chaîne, jusqu'à longueur maximale octets et à partir de la offset.

Une fonction POST avec ceux-ci peut simplement ressembler à ceci:

<?php

function post_request($url, array $params) {
  $query_content = http_build_query($params);
  $fp = fopen($url, 'r', FALSE, // do not use_include_path
    stream_context_create([
    'http' => [
      'header'  => [ // header array does not need '\r\n'
        'Content-type: application/x-www-form-urlencoded',
        'Content-Length: ' . strlen($query_content)
      ],
      'method'  => 'POST',
      'content' => $query_content
    ]
  ]));
  if ($fp === FALSE) {
    fclose($fp);
    return json_encode(['error' => 'Failed to get contents...']);
  }
  $result = stream_get_contents($fp); // no maxlength/offset
  fclose($fp);
  return $result;
}
10
CPHPython

Il y en a encore un que vous pouvez utiliser

<?php
$fields = array(
    'name' => 'mike',
    'pass' => 'se_ret'
);
$files = array(
    array(
        'name' => 'uimg',
        'type' => 'image/jpeg',
        'file' => './profile.jpg',
    )
);

$response = http_post_fields("http://www.example.com/", $fields, $files);
?>

Cliquez ici pour plus de détails

5
Code

Je cherchais un problème similaire et ai trouvé une meilleure approche pour le faire. Alors voilà.

Vous pouvez simplement mettre la ligne suivante sur la page de redirection (par exemple page1.php).

header("Location: URL", TRUE, 307); // Replace URL with to be redirected URL, e.g. final.php

J'ai besoin de cela pour rediriger POST demandes d'appels RESTE API Cette solution est capable de rediriger avec des données de publication ainsi que des valeurs d'en-tête personnalisées.

Voici le lien de référence .

5
Arindam Nayak

Essayez le paquet HTTP_Request2 de PEAR pour envoyer facilement des demandes POST. Vous pouvez aussi utiliser les fonctions curl de PHP ou utiliser un PHP stream context .

HTTP_Request2 permet également de simuler le serveur afin que vous puissiez tester votre code à l'unité facilement

1
cweiske

La meilleure façon d’envoyer des demandes GET ou POST avec PHP est la suivante:

<?php
    $r = new HttpRequest('http://example.com/form.php', HttpRequest::METH_POST);
    $r->setOptions(array('cookies' => array('lang' => 'de')));
    $r->addPostFields(array('user' => 'mike', 'pass' => 's3c|r3t'));

    try {
        echo $r->send()->getBody();
    } catch (HttpException $ex) {
        echo $ex;
    }
?>

Le code provient de la documentation officielle ici http://php.net/manual/it/httprequest.send.php

0
Imran Zahoor