PHP file_get_contents() 和设置请求头

146

使用PHP的file_get_contents()函数,能否发送HTTP头信息?

我知道你可以从php.ini文件中发送用户代理。但是,你是否也可以使用file_get_contents()函数发送其他信息,例如HTTP_ACCEPTHTTP_ACCEPT_LANGUAGEHTTP_CONNECTION

或者有另外一个能够实现这个功能的函数吗?

7个回答

379

实际上,经过对file_get_contents()函数的进一步阅读:

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

// DOCS: https://www.php.net/manual/en/function.stream-context-create.php
$context = stream_context_create($opts);

// Open the file using the HTTP headers set above
// DOCS: https://www.php.net/manual/en/function.file-get-contents.php
$file = file_get_contents('http://www.example.com/', false, $context);

你可以尝试按照这种模式来实现你想要的目标,虽然我个人没有测试过。如果不起作用,可以查看我的其他答案。


21
这是此页面上唯一有用的答案。 - Gordon
12
我希望这里有更多的人可以直接回答这个问题,而不仅仅是指向cURL页面。谢谢。 - mrbellek
3
突然好奇:file_get_contents() 的默认用户代理是什么?它是否指定了一个? - Raptor
5
请设置用户代理为SomeBrowser v42.0.4711,方法是前往http://user-agent.me复制您的用户代理,或者编辑php.ini全局修改。请注意不要改变原意。 - jaggedsoft
1
@NextLocal 我是在询问默认值,而不是给它赋值。 - Raptor
显示剩余5条评论

109

以下是对我有效的方法(多米尼克只是短了一行)。

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

9
不应伪装浏览器的用户代理,而是为您的工具创建一个User-Agent字符串。http://www-archive.mozilla.org/build/revised-user-agent-strings.html可以提供有关格式的一些想法。 - Dereckson
2
@Vince 我认为在某些情况下可能会双向工作。像这样设置代理头,作为字符串,在我的情况下起作用(WAF需要非空用户代理才能通过请求)。 - dhaupin
3
PHP文档指出,如果同时指定了"User-Agent" headeruser_agent数组元素,则"User-Agent" header将覆盖user_agent。需要注意的是,在使用中两者都可以被使用。 - MrWhite
1
请注意:在包含特殊字符(如\n或\r)的字符串中,不要使用单引号。PHP将无法正确解释它们,并且在发送标头的情况下,您的标头将无法正确发送。 - ak93
1
@Fanky,最简单的方式可能是“YourTool/1.0.0”。当你发布新版本时,你也可以升级用户代理版本,如“YourTool/1.3.5”。 - Dereckson
显示剩余2条评论

43
你可以使用这个变量在file_get_contents()函数后获取响应头。
代码:
  file_get_contents("http://example.com");
  var_dump($http_response_header);

输出:

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"
}

8
这完全没有回答这个问题。 - Gordon
39
也许不是,但它回答了标题中隐含的相反问题,即如何从file_get_contents中读取响应头。这就是谷歌在研究那个问题时停留的地方。 - Rich Remer
他并不是在问那个问题。他在问如何使用file_get_content函数来发送请求头信息。 - mmoreram

0

使用php cURL库可能是正确的选择,因为该库比简单的file_get_contents(...)具有更多功能。

一个例子:

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

6
您展示的代码片段也可以使用 file_get_contents 轻松实现,而且我还没有遇到过只能使用 cURL 才能实现的应用案例。 - Gordon
1
变量 $header 不存在,也许你想写的是 $headers?值得纠正。 - Olindholm

0

-4

如果您不需要HTTPS且系统上没有可用的curl,您可以使用fsockopen

此函数打开一个连接,您可以像使用普通文件句柄一样进行读写操作。


3
是的,但这也意味着OP必须手动实现HTTP协议。此外,OP并没有询问file_get_contents的替代方案,因此这算是一个离题的答案。 - Gordon
一点意义都没有 - mmoreram

-5

不幸的是,看起来file_get_contents()并没有提供那种程度的控制。cURL扩展通常是首选,但我强烈推荐PECL_HTTP扩展(http://pecl.php.net/package/pecl_http)用于非常简单和直接的HTTP请求。(比cURL更容易使用)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接