PHP file_get_contents () et définition des en-têtes de requête

121

Avec PHP, est-il possible d'envoyer des en-têtes HTTP avec file_get_contents()?

Je sais que vous pouvez envoyer l'agent utilisateur à partir de votre php.inifichier. Cependant, pouvez-vous également envoyer d'autres informations telles queHTTP_ACCEPT , HTTP_ACCEPT_LANGUAGEet HTTP_CONNECTIONavec file_get_contents()?

Ou y a-t-il une autre fonction qui accomplira cela?

Marcus
la source

Réponses:

319

En fait, après lecture supplémentaire de la file_get_contents()fonction:

// Create a stream
$opts = [
    "http" => [
        "method" => "GET",
        "header" => "Accept-language: en\r\n" .
            "Cookie: foo=bar\r\n"
    ]
];

$context = stream_context_create($opts);

// Open the file using the HTTP headers set above
$file = file_get_contents('http://www.example.com/', false, $context);

Vous pourrez peut-être suivre ce modèle pour atteindre ce que vous cherchez, mais je ne l'ai pas personnellement testé. (et si cela ne fonctionne pas, n'hésitez pas à consulter mon autre réponse)

Dominic Barnes
la source
18
c'est la seule réponse utile sur cette page
Gordon
9
Je souhaite que plus de personnes ici donnent la réponse réelle à cette question au lieu de simplement pointer vers la page cURL. Merci.
Merijn
3
soudainement curieux: de quoi est l' agent utilisateur par défautfile_get_contents() ? en précise-t-il un?
Raptor
5
@Raptor ini_set('user_agent', 'SomeBrowser v42.0.4711');allez sur user-agent.me et copiez le vôtre à partir de là .. ou éditez php.ini pour le changer globalement
jaggedsoft
88

Voici ce qui a fonctionné pour moi (Dominic était juste une ligne courte).

$url = "";

$options = array(
  'http'=>array(
    'method'=>"GET",
    'header'=>"Accept-language: en\r\n" .
              "Cookie: foo=bar\r\n" .  // check function.stream-context-create on php.net
              "User-Agent: Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.102011-10-16 20:23:10\r\n" // i.e. An iPad 
  )
);

$context = stream_context_create($options);
$file = file_get_contents($url, false, $context);
Fabrice
la source
6
Vous ne devez pas vous faire passer pour l'agent utilisateur d'un navigateur. Au lieu de cela, créez une chaîne User-Agent pour votre outil. www-archive.mozilla.org/build/revised-user-agent-strings.html pourrait donner une idée du format.
Dereckson
1
@Vince, je pense que cela peut fonctionner dans les deux sens dans certaines circonstances. Définir l'en-tête de l'agent comme ça, en tant que chaîne, a fonctionné dans mon cas (WAF avait besoin d'un agent utilisateur non vide pour que la demande soit
acceptée
3
@Vince La documentation PHP indique que les deux peuvent être utilisés et que "User-Agent" headerremplacera l' user_agentélément du tableau, si les deux sont spécifiés.
MrWhite du
REMARQUE: n'utilisez jamais de guillemets simples avec des chaînes contenant des caractères spéciaux tels que \ n ou \ r. PHP ne les interprétera pas correctement et en cas d'envoi d'en-têtes, vos en-têtes ne seront pas envoyés correctement.
ak93
1
@Fanky le plus simple pourrait être "YourTool / 1.0.0". Lorsque vous publiez une nouvelle version, vous pouvez également modifier la version de l'agent utilisateur, "YourTool / 1.3.5".
Dereckson
38

Vous pouvez utiliser cette variable pour récupérer les en-têtes de réponse après la file_get_contents()fonction.

Code:

  file_get_contents("http://example.com");
  var_dump($http_response_header);

Production:

array(9) {
  [0]=>
  string(15) "HTTP/1.1 200 OK"
  [1]=>
  string(35) "Date: Sat, 12 Apr 2008 17:30:38 GMT"
  [2]=>
  string(29) "Server: Apache/2.2.3 (CentOS)"
  [3]=>
  string(44) "Last-Modified: Tue, 15 Nov 2005 13:24:10 GMT"
  [4]=>
  string(27) "ETag: "280100-1b6-80bfd280""
  [5]=>
  string(20) "Accept-Ranges: bytes"
  [6]=>
  string(19) "Content-Length: 438"
  [7]=>
  string(17) "Connection: close"
  [8]=>
  string(38) "Content-Type: text/html; charset=UTF-8"
}
ali_sed
la source
6
cela ne répond pas du tout à la question.
Gordon
32
Peut-être pas, mais cela répond à la question opposée impliquée dans le titre, à savoir comment lire les en-têtes de réponse à partir de file_get_contents. Et c'est là que Google atterrit lors de l'enquête sur CETTE question.
Rich Remer
0

Oui.

Lors de l'appel file_get_contentssur une URL, il faut utiliser la stream_create_contextfonction, qui est assez bien documentée sur php.net.

Ceci est plus ou moins exactement couvert sur la page suivante sur php.net dans la section des commentaires des utilisateurs: http://php.net/manual/en/function.stream-context-create.php

Laereom
la source
-1

L'utilisation des bibliothèques php cURL sera probablement la bonne solution, car cette bibliothèque a plus de fonctionnalités que le simple file_get_contents(...) .

Un exemple:

<?php
$ch = curl_init();
$headers = array('HTTP_ACCEPT: Something', 'HTTP_ACCEPT_LANGUAGE: fr, en, da, nl', 'HTTP_CONNECTION: Something');

curl_setopt($ch, CURLOPT_URL, "http://localhost"); # URL to post to
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 ); # return into a variable
curl_setopt($ch, CURLOPT_HTTPHEADER, $header ); # custom headers, see above
$result = curl_exec( $ch ); # run!
curl_close($ch);
?>
Phidah
la source
5
L'extrait que vous montrez est également facile à réaliser file_get_contentset je n'ai pas encore trouvé de cas d'utilisation que vous ne pouvez réaliser qu'avec cURL.
Gordon
-2

Si vous n'avez pas besoin de HTTPS et que curl n'est pas disponible sur votre système, vous pouvez utiliser fsockopen

Cette fonction ouvre une connexion à partir de laquelle vous pouvez à la fois lire et écrire comme vous le feriez avec un descripteur de fichier normal.

AlexB
la source
2
oui, mais cela signifierait également que l'OP doit implémenter le protocole HTTP à la main. De plus, le PO n'a pas posé de questions sur les alternatives file_get_contents, c'est donc une réponse hors sujet.
Gordon
-4

Malheureusement, il ne semble pas file_get_contents()vraiment offrir ce degré de contrôle. L'extension cURL est généralement la première à apparaître, mais je recommande vivement l'extension PECL_HTTP ( http://pecl.php.net/package/pecl_http ) pour les requêtes HTTP très simples et directes. (c'est beaucoup plus facile à travailler qu'avec cURL)

Dominic Barnes
la source