Comment publier des données en PHP en utilisant file_get_contents?

299

J'utilise la fonction de PHP file_get_contents()pour récupérer le contenu d'une URL, puis je traite les en-têtes via la variable $http_response_header.

Maintenant, le problème est que certaines URL ont besoin que certaines données soient publiées sur l'URL (par exemple, les pages de connexion).

Comment je fais ça?

Je me rends compte qu'en utilisant stream_context, je peux peut-être le faire, mais je ne suis pas tout à fait clair.

Merci.

Paras Chopra
la source
8
Cela devrait être voté à l'infini. Il n'y a aucune raison d'utiliser Curl / Guzzle ou toute autre bibliothèque de fantaisie si vous avez une fonctionnalité PHP brute qui fait le travail.
Omar Abid

Réponses:

589

L'envoi d'une requête HTTP POST en utilisant file_get_contentsn'est pas si difficile, en fait: comme vous l'avez deviné, vous devez utiliser le $contextparamètre.


Il y a un exemple donné dans le manuel PHP, sur cette page: Options de contexte HTTP (citation) :

$postdata = http_build_query(
    array(
        'var1' => 'some content',
        'var2' => 'doh'
    )
);

$opts = array('http' =>
    array(
        'method'  => 'POST',
        'header'  => 'Content-Type: application/x-www-form-urlencoded',
        'content' => $postdata
    )
);

$context  = stream_context_create($opts);

$result = file_get_contents('http://example.com/submit.php', false, $context);

Fondamentalement, vous devez créer un flux, avec les bonnes options (il y a une liste complète sur cette page) , et l'utiliser comme troisième paramètre pour file_get_contents- rien de plus ;-)


En guise de note: de manière générale, pour envoyer des requêtes HTTP POST, nous avons tendance à utiliser curl, qui offre beaucoup d'options, mais les flux sont l'une des belles choses de PHP que personne ne connaît ... dommage. .

Pascal MARTIN
la source
1
Merci. Je suppose que je peux insérer le contenu de $ _POST dans $ postdata si j'ai besoin de passer les mêmes paramètres POST à ​​la page demandée?
Paras Chopra
6
Je suppose que vous pouvez faire quelque chose comme ça; mais contentne doit pas être un tableau PHP: il doit être un querystring (il faut a ce format: param1=value1&param2=value2&param3=value3) ;; ce qui signifie que vous devrez probablement utiliserhttp_build_query($_POST)
Pascal MARTIN
2
Merveilleux! Je cherchais un moyen de transmettre les données POST à ​​une autre page qui est réalisable en le faisant $postdata = http_build_query($_POST).
Liam Newmarch
1
assez intéressant cela ne fonctionne pas du tout pour moi je l'ai essayé pendant quelques heures et toutes mes requets sont transformées en requêtes de recherche
WojonsTech
1
Pour envoyer plusieurs valeurs d'en-tête, jetez-les toutes dans une même chaîne avec des \r\nsauts de ligne - voir: stackoverflow.com/a/2107792/404960
rymo
20

Une alternative, vous pouvez également utiliser fopen

$params = array('http' => array(
    'method' => 'POST',
    'content' => 'toto=1&tata=2'
));

$ctx = stream_context_create($params);
$fp = @fopen($sUrl, 'rb', false, $ctx);
if (!$fp)
{
    throw new Exception("Problem with $sUrl, $php_errormsg");
}

$response = @stream_get_contents($fp);
if ($response === false) 
{
    throw new Exception("Problem reading data from $sUrl, $php_errormsg");
}
Macbric
la source
Pour une raison quelconque, cela a fonctionné pour moi, mais l'exemple officiel de PHP n'a pas fonctionné. +1 pour le toto=1&tata=2aussi. fopenCependant, je n'ai pas utilisé le .
Michael Yaworski
4
@ Ġiĺàɗ Nous n'appelons pas les gens «noob» ici. Il s'agit d'un avertissement amical contre une telle.
Daedalus
0
$sUrl = 'http://www.linktopage.com/login/';
$params = array('http' => array(
    'method'  => 'POST',
    'content' => 'username=admin195&password=d123456789'
));

$ctx = stream_context_create($params);
$fp = @fopen($sUrl, 'rb', false, $ctx);
if(!$fp) {
    throw new Exception("Problem with $sUrl, $php_errormsg");
}

$response = @stream_get_contents($fp);
if($response === false) {
    throw new Exception("Problem reading data from $sUrl, $php_errormsg");
}
user2525449
la source
2
S'il vous plaît, essayez de fournir une réponse élaborée au lieu de simplement copier / coller du code.
Felipe Leão
1
C'est aussi inutilement compliqué. Vous pouvez utiliser file_get_contentsau lieu de fopen+ stream_get_contents. Et vous ne fermez même pas le "fichier". Voir la réponse acceptée par @PascalMARTIN.
Martin Prikryl