PHP file_get_contents () i ustawianie nagłówków żądań

121

Czy w PHP można wysyłać nagłówki HTTP z file_get_contents()?

Wiem, że możesz wysłać agenta użytkownika ze swojego php.inipliku. Jednakże, można również wysłać inne informacje, takie jak HTTP_ACCEPT, HTTP_ACCEPT_LANGUAGEoraz HTTP_CONNECTIONz file_get_contents()?

A może jest inna funkcja, która to umożliwi?

Marcus
źródło

Odpowiedzi:

319

Właściwie po dalszym czytaniu file_get_contents()funkcji:

// 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);

Być może będziesz w stanie podążać za tym wzorem, aby osiągnąć to, do czego dążysz, chociaż osobiście tego nie testowałem. (a jeśli to nie zadziała, sprawdź moją drugą odpowiedź)

Dominic Barnes
źródło
18
to jedyna użyteczna odpowiedź na tej stronie
Gordon,
9
Chciałbym, aby więcej osób tutaj udzielało rzeczywistej odpowiedzi na to pytanie, zamiast wskazywać tylko stronę cURL. Dzięki.
Merijn,
3
nagle zaciekawiony: jaki jest domyślny agent użytkownika file_get_contents()? czy to określa?
Raptor
5
@Raptor ini_set('user_agent', 'SomeBrowser v42.0.4711');przejdź do user-agent.me i skopiuj stamtąd swój .. lub edytuj php.ini, aby zmienić go globalnie
jaggedsoft
88

Oto, co zadziałało dla mnie (Dominic był krótki tylko o jedną linię).

$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
źródło
6
Nie powinieneś podszywać się pod klienta użytkownika przeglądarki. Zamiast tego utwórz ciąg User-Agent dla swojego narzędzia. www-archive.mozilla.org/build/revised-user-agent-strings.html może dać pewne wyobrażenie o formacie.
Dereckson,
1
@Vince, myślę, że w pewnych okolicznościach może to działać w obie strony. Ustawienie nagłówka agenta w ten sposób, jako ciągu znaków, działało w moim przypadku (WAF potrzebował niepustego agenta użytkownika dla żądania przejścia)
dhaupin
3
@Vince Dokumentacja PHP stwierdza, że oba mogą być używane, a "User-Agent" headerprzesłoni user_agentelement tablicy, jeśli oba są określone.
MrWhite
UWAGA: Nigdy nie używaj pojedynczych cudzysłowów z łańcuchami zawierającymi znaki specjalne, takie jak \ n lub \ r. PHP nie zinterpretuje ich poprawnie iw przypadku wysłania nagłówków, Twoje nagłówki nie zostaną wysłane poprawnie.
ak93
1
@Fanky, najprostszym może być „YourTool / 1.0.0”. Kiedy wydajesz nową wersję, możesz także zmienić wersję klienta użytkownika, „YourTool / 1.3.5”.
Dereckson
38

Możesz użyć tej zmiennej do pobrania nagłówków odpowiedzi po file_get_contents()funkcji.

Kod:

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

Wynik:

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
źródło
6
to wcale nie odpowiada na pytanie.
Gordon
32
Może nie, ale odpowiada na przeciwne pytanie zawarte w tytule, czyli jak czytać nagłówki odpowiedzi z pliku file_get_contents. I tu właśnie ląduje Google, badając to pytanie.
Rich Remer,
0

Tak.

Podczas wywoływania file_get_contentsadresu URL należy skorzystać z stream_create_contextfunkcji, która jest dość dobrze udokumentowana na php.net.

Jest to mniej więcej dokładnie omówione na następującej stronie php.net w sekcji komentarzy użytkowników: http://php.net/manual/en/function.stream-context-create.php

Laereom
źródło
-1

Korzystanie z bibliotek php cURL będzie prawdopodobnie właściwą drogą, ponieważ ta biblioteka ma więcej funkcji niż prosta file_get_contents(...).

Przykład:

<?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
źródło
5
Fragment, który pokazujesz, jest również łatwy do osiągnięcia, file_get_contentsa ja jeszcze nie znalazłem przypadku użycia, który można osiągnąć tylko za pomocą cURL.
Gordon
-2

Jeśli nie potrzebujesz protokołu HTTPS, a funkcja curl nie jest dostępna w Twoim systemie, możesz użyć fsockopen

Ta funkcja otwiera połączenie, z którego możesz zarówno czytać, jak i pisać, tak jak w przypadku normalnego uchwytu pliku.

AlexB
źródło
2
tak, ale oznaczałoby to również, że OP musi ręcznie implementować protokół HTTP. Ponadto PO nie pytał o alternatywy, file_get_contentswięc jest to nieco nie na temat odpowiedzi.
Gordon
-4

Niestety, wygląda na to, że nie file_get_contents()oferuje takiego stopnia kontroli. Rozszerzenie cURL jest zwykle pierwszym, które pojawia się jako pierwsze, ale bardzo polecam rozszerzenie PECL_HTTP ( http://pecl.php.net/package/pecl_http ) dla bardzo prostych i nieskomplikowanych żądań HTTP. (znacznie łatwiej się z nim pracuje niż cURL)

Dominic Barnes
źródło