2024 年 PHP Conference Japan

HTTP 內容選項

HTTP 內容選項HTTP 內容選項列表

說明

http://https:// 傳輸的內容選項。

選項

method 字串

GETPOST 或遠端伺服器支援的任何其他 HTTP 方法。

預設為 GET

header 陣列字串

請求期間要發送的額外標頭。此選項中的值會覆蓋其他值(例如 User-agent:Host:Authentication:),即使在跟隨 Location: 重定向時也是如此。因此,如果啟用了 follow_location,則不建議設定 Host: 標頭。

user_agent 字串

要與 User-Agent: 標頭一起發送的值。僅當在上面的 header 上下文選項中*未*指定使用者代理時,才會使用此值。

預設情況下,會使用 user_agent php.ini 設定。

content 字串

在標頭之後要發送的額外資料。通常與 POST 或 PUT 請求一起使用。

proxy 字串

指定代理伺服器位址的 URI(例如 tcp://proxy.example.com:5100)。

request_fulluri 布林值

設定為 true 時,建構請求時將使用整個 URI(例如 GET http://www.example.com/path/to/file.html HTTP/1.0)。雖然這是非標準的請求格式,但某些代理伺服器需要它。

預設為 false

follow_location 整數

跟隨 Location 標頭重定向。設定為 0 可停用。

預設為 1

max_redirects 整數

要跟隨的最大重定向次數。值 1 或更小表示不跟隨任何重定向。

預設為 20

protocol_version 浮點數

HTTP 協定版本。

從 PHP 8.0.0 開始,預設值為 1.1;在該版本之前,預設值為 1.0

timeout 浮點數

讀取逾時(秒),以 浮點數 指定(例如 10.5)。

預設情況下,會使用 default_socket_timeout php.ini 設定。

ignore_errors 布林值

即使在失敗狀態碼時也擷取內容。

預設為 false

範例

範例 #1 擷取頁面並傳送 POST 資料

<?php

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

?>

範例 #2 忽略重新導向,但擷取標頭和內容

<?php

$url
= "http://www.example.org/header.php";

$opts = array('http' =>
array(
'method' => 'GET',
'max_redirects' => '0',
'ignore_errors' => '1'
)
);

$context = stream_context_create($opts);
$stream = fopen($url, 'r', false, $context);

// 標頭資訊以及串流的詮釋資料
var_dump(stream_get_meta_data($stream));

// $url 中的實際資料
var_dump(stream_get_contents($stream));
fclose($stream);
?>

注意事項

注意底層通訊端串流環境選項
底層傳輸方式 underlying transport 可能支援額外的上下文選項。對於 http:// 串流,請參考 tcp:// 傳輸方式的上下文選項。對於 https:// 串流,請參考 ssl:// 傳輸方式的上下文選項。

注意HTTP 狀態行
當此串流包裝器遵循重新導向時,由 stream_get_meta_data() 返回的 wrapper_data 可能不一定包含實際應用於索引 0 處內容資料的 HTTP 狀態行。

array (
  'wrapper_data' =>
  array (
    0 => 'HTTP/1.0 301 Moved Permanently',
    1 => 'Cache-Control: no-cache',
    2 => 'Connection: close',
    3 => 'Location: http://example.com/foo.jpg',
    4 => 'HTTP/1.1 200 OK',
    ...
第一個請求返回 301(永久重新導向),因此串流包裝器自動遵循重新導向以獲得 200 回應(索引 = 4)。

新增註解

使用者貢獻的註解 11 則註解

nate
10 年前
請注意,如果您將 protocol_version 選項設定為 1.1,並且您請求的伺服器設定為使用 Keep-Alive 連線,則函式(fopen、file_get_contents 等)將會「變慢」且需要很長時間才能完成。這是 HTTP 1.1 協定的特性,您不太可能在 PHP 的串流上下文中使用它。

只需在請求中新增「Connection: close」標頭即可消除 Keep-Alive 超時

<?php
// php 5.4 : 陣列語法和帶有陣列值的 header 選項
$data = file_get_contents('http://www.example.com/', null, stream_context_create([
'http' => [
'protocol_version' => 1.1,
'header' => [
'Connection: close',
],
],
]));
?>
daniel dot peder at gmail dot com
7 年前
請注意,http 和 https 協定都需要相同的 'http' 上下文關鍵字

<?php

// 正確範例:
// 這個會如預期般運作
// 注意網址使用 https 但 context 使用 http
$correct_data = file_get_contents('https://example.com', false, stream_context_create(array('http' => array(...))));

// 錯誤範例:
// 這個不會運作,context 會被忽略
// 注意網址使用 https,context 也使用 https
$correct_data = file_get_contents('https://example.com', false, stream_context_create(array('https' => array(...))));
daniel.peder (a) gmail.com
7 年前
請注意,http 和 https 傳輸都需要使用相同的 context 名稱 http

// 正確範例
// 這個會如預期般運作
// 注意網址使用 https 但 context 使用 http
$correct_data = file_get_contents('https://example.com', false, stream_context_create(array('http' => array(...))));

// 錯誤範例
// 這個不會運作,context 會被忽略
// 注意網址使用 https,context 也使用 https
$correct_data = file_get_contents('https://example.com', false, stream_context_create(array('https' => array(...))));
ASchmidt at Anamera dot net
3 年前
使用預設值

'follow_location' => 1

時,請務必「不要」在 'header' 陣列中包含 "Host:" 標頭。

如果主機設定為 "mydomain.com",且該網站有重定向到 "www.mydomain.com"(相當常見),則對 "http://mydomain.com" 的初始請求會得到預期的回應:

HTTP/1.1 301 Moved Permanently
Location: http://www.mydomain.com/

然而,後續請求「不會」如預期般以新的 "location" 值取代原始的 "host" 標頭。因此,每個「follow-location」請求將會再次由原始主機 "http://mydomain.com" 提供服務,並持續重定向迴圈,直到 'max_redirects' 已達上限。

(詳細資訊:https://bugs.php.net/bug.php?id=77889
ywarnier at beeznest dot org
7 年前
請注意,將 request_fulluri 設定為 true 會「更改」接收端 $_SERVER['REQUEST_URI] 的值(從 /abc.php 改為 http://domain.com/abc.php)。
gourav sarkar
13 年前
使用方法(POST 和 GET)時請注意大小寫…它必須始終為大寫。如果您使用小寫,它將無法運作。
aruntechguy at outlook dot com
7 年前
如果您想在使用 get_headers() 時使用基本驗證,請使用以下 stream_context 選項。

我在這裡使用 HEAD 方法,但您也可以隨意使用 GET。

<?php
$targetUrl
= 'http 或 https 目標網址';
$basicAuth = base64_encode('使用者名稱:密碼');

stream_context_set_default(
[
'http' => [
'method' => 'HEAD',
'header' => 'Authorization: Basic ' . $basicAuth
]
]
);
$result = get_headers($targetUrl);

print_r($result);
njt1982 at yahoo dot com
5 個月前
值得注意的是,`header` 陣列似乎只接受字串陣列,而不接受關聯式陣列。

我剛花了一段時間除錯一個不如預期運作的問題(雖然沒有錯誤訊息),最後是透過將標頭的關聯式陣列轉換成簡單的字串陣列來解決的。
vchampion at gmail dot com
12 年前
如果您使用代理伺服器並遇到錯誤訊息「fopen(http://example.com): failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request」,請注意,在許多情況下,您還需要在串流選項中將參數「request_fulluri」設定為「true」。如果沒有這個選項,PHP 腳本會將空請求以「GET / HTTP/0.0」的形式發送到伺服器,而代理伺服器會以「HTTP 400」錯誤訊息回覆。

例如(有效的範例)
<?php
$stream
= stream_context_create(Array("http" => Array("method" => "GET",
"timeout" => 20,
"header" => "User-agent: Myagent",
"proxy" => "tcp://my-proxy.localnet:3128",
'request_fulluri' => True /* 沒有這個選項會得到 HTTP 錯誤! */
)));

if (
$fp = fopen("http://example.com", 'r', false, $stream) ) {
print
"成功";
}
?>

P>S> PHP 5.3.17
jay
9 年前
記得要將內容與 Content-type 相符

<?php

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

$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/json', // 在這裡...
'content' => json_encode($data) // 和這裡。
)
);

. . .

?>
chris
10 年前
我嘗試透過代理伺服器使用 fopen 對安全網址發出請求時遇到了一些問題。 我不斷從遠端主機收到 400 Bad Request 的錯誤。 它將代理網址接收為 SNI 主機名稱。 為了避開這個問題,我必須明確地將 SNI 主機名稱設定為我嘗試連線的網域。 這顯然是這個錯誤中概述的問題

https://bugs.php.net/bug.php?id=63519

<?php
$domain
= parse_url($file, PHP_URL_HOST);
$proxy_string = "tcp://" . WP_PROXY_HOST . ":" . WP_PROXY_PORT;
$opts = array(
'http' => array( 'proxy' => $proxy_string ),
'ssl' => array( 'SNI_enabled' => true, 'SNI_server_name' => $domain));
$context = stream_context_create($opts);
$handle = fopen( $file, 'r', false, $context );
?>
To Top