2024 年 PHP 日本研討會

curl_getinfo

(PHP 4 >= 4.0.4, PHP 5, PHP 7, PHP 8)

curl_getinfo取得關於特定傳輸的資訊

說明

curl_getinfo(CurlHandle $handle, ?int $option = null): mixed

取得上次傳輸的相關資訊。

參數

handle

curl_init() 返回的 cURL 句柄。

option

CURLINFO_* 常數其中之一。

傳回值

如果給定 option,則返回其值。否則,返回包含以下元素(對應於 option)的關聯陣列,或者失敗時返回 false

  • "url"
  • "content_type"
  • "http_code"
  • "header_size"
  • "request_size"
  • "filetime"
  • "ssl_verify_result"
  • "redirect_count"
  • "total_time"
  • "namelookup_time"
  • "connect_time"
  • "pretransfer_time"
  • "size_upload"
  • "size_download"
  • "speed_download"
  • "speed_upload"
  • "download_content_length"
  • "upload_content_length"
  • "starttransfer_time"
  • "redirect_time"
  • "certinfo"
  • "primary_ip"
  • "primary_port"
  • "local_ip"
  • "local_port"
  • "redirect_url"
  • "request_header" (僅在先前呼叫 curl_setopt() 時設定 CURLINFO_HEADER_OUT 才會設定此值)
  • "posttransfer_time_us" (PHP 8.4.0 和 cURL 8.10.0 起可用)
請注意,私有資料不包含在關聯陣列中,必須使用 CURLINFO_PRIVATE 選項單獨擷取。

範例

範例 #1 curl_getinfo() 範例

<?php
// 建立 cURL 句柄
$ch = curl_init('http://www.example.com/');

// 執行
curl_exec($ch);

// 檢查是否有錯誤發生
if (!curl_errno($ch)) {
$info = curl_getinfo($ch);
echo
'花了 ', $info['total_time'], ' 秒發送請求到 ', $info['url'], "\n";
}

// 關閉句柄
curl_close($ch);
?>

範例 #2 使用 option 參數的 curl_getinfo() 範例

<?php
// 建立 cURL 句柄
$ch = curl_init('http://www.example.com/');

// 執行
curl_exec($ch);

// 檢查 HTTP 狀態碼
if (!curl_errno($ch)) {
switch (
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE)) {
case
200: # 正常
break;
default:
echo
'非預期的 HTTP 狀態碼: ', $http_code, "\n";
}
}

// 關閉句柄
curl_close($ch);
?>

注意事項

備註:

如果句柄被重複使用,則此函數收集的資訊會被保留。這表示除非此函數內部覆蓋了統計資訊,否則會返回先前的資訊。

新增備註

使用者貢獻的備註 15 則備註

ssttoo at hotmail dot com
20 年前
以下是準備好貼上到 ini 樣式檔案中的回應碼。可用於提供更具描述性的訊息,對應於 curl_getinfo() 返回的陣列的 'http_code' 索引。
這些取自 W3C 的 HTTP/1.1:狀態碼定義,網址如下:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

[資訊 1xx]
100="繼續"
101="正在切換通訊協定"

[成功 2xx]
200="正常"
201="已建立"
202="已接受"
203="非授權資訊"
204="無內容"
205="重設內容"
206="部分內容"

[重新導向 3xx]
300="多重選擇"
301="永久移動"
302="已找到"
303="查看其他"
304="未修改"
305="使用代理伺服器"
306="(未使用)"
307="暫時重新導向"

[用戶端錯誤 4xx]
400="錯誤的請求"
401="未經授權"
402="需要付款"
403="禁止"
404="找不到"
405="不允許的方法"
406="不可接受"
407="需要代理伺服器驗證"
408="請求逾時"
409="衝突"
410="已刪除"
411="需要長度"
412="前提條件失敗"
413="請求實體過大"
414="請求 URI 過長"
415="不支援的媒體類型"
416="請求的範圍不滿足"
417="期望失敗"

[伺服器錯誤 5xx]
500="內部伺服器錯誤"
501="未實作"
502="閘道器錯誤"
503="服務無法使用"
504="閘道器逾時"
505="不支援的 HTTP 版本"

以及一個使用範例
<?php
$ch
= curl_init(); // 建立 cURL 句柄 (ch)
if (!$ch) {
die(
"無法初始化 cURL 句柄");
}
// 設定一些 cURL 選項
$ret = curl_setopt($ch, CURLOPT_URL, "http://mail.yahoo.com");
$ret = curl_setopt($ch, CURLOPT_HEADER, 1);
$ret = curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$ret = curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
$ret = curl_setopt($ch, CURLOPT_TIMEOUT, 30);

// 執行
$ret = curl_exec($ch);

if (empty(
$ret)) {
// 發生某種錯誤
die(curl_error($ch));
curl_close($ch); // 關閉 cURL 處理器
} else {
$info = curl_getinfo($ch);
curl_close($ch); // 關閉 cURL 處理器

if (empty($info['http_code'])) {
die(
"未傳回 HTTP 狀態碼");
} else {
// 載入 HTTP 狀態碼
$http_codes = parse_ini_file("path/to/the/ini/file/I/pasted/above");

// 顯示結果
echo "伺服器回應:<br />";
echo
$info['http_code'] . " " . $http_codes[$info['http_code']];
}

}
?>
vince
14 年前
CURLINFO_HTTP_CODE 傳回的不是字串,如文件中所述,而是一個整數。

<?php
$c
= curl_init('http://www.example.com/');
if(
curl_getinfo($c, CURLINFO_HTTP_CODE) === '200') echo "CURLINFO_HTTP_CODE returns a string.";
if(
curl_getinfo($c, CURLINFO_HTTP_CODE) === 200) echo "CURLINFO_HTTP_CODE returns an integer.";
curl_close($c);
?>

回傳

"CURLINFO_HTTP_CODE 傳回一個整數。"
public-mail at alekciy dot ru
9 年前
注意,header_size 包含 "\r\n\r\n"。所以,如果您使用 CURLOPT_FOLLOWLOCATION>0、CURLOPT_HEADER=true、CURLOPT_RETURNTRANSFER=true,正確分割 header/body 的方法如下:

$response = curl_exec($ch);
$curl_info = curl_getinfo($ch);
curl_close($ch);
$header_size = $curl_info['header_size'];
$header = substr($response, 0, $header_size);
$body = substr($response, $header_size);
nikita dot bulatenko at gmail dot com
11 年前
CURLINFO_SSL_VERIFYRESULT 錯誤碼
0:正常,操作成功。
2:無法取得發行者憑證
3:無法取得憑證 CRL
4:無法解密憑證的簽章
5:無法解密 CRL 的簽章
6:無法解碼發行者公鑰
7:憑證簽章失敗
8:CRL 簽章失敗
9:憑證尚未生效
10:憑證已過期
11:CRL 尚未生效
12:CRL 已過期
13:憑證 notBefore 欄位的格式錯誤
14:憑證 notAfter 欄位的格式錯誤
15:CRL lastUpdate 欄位的格式錯誤
16:CRL nextUpdate 欄位的格式錯誤
17:記憶體不足
18:自簽憑證
19:憑證鏈中的自簽憑證
20:無法取得本地發行者憑證
21:無法驗證第一個憑證
22:憑證鏈過長
23:憑證已撤銷
24:無效的 CA 憑證
25:超過路徑長度限制
26:不支援的憑證用途
27:憑證不受信任
28:憑證遭拒
29:主體發行者不符
30:授權單位與主體金鑰識別碼不符
31:授權單位與發行者序號不符
32:金鑰用途不包含憑證簽署
50:應用程式驗證失敗
詳情請見 http://www.openssl.org/docs/apps/verify.html#VERIFY_OPERATION
qrworld.net
10 年前
這裡有一個我用來使用 cURL 取得 URL 內容的函式。它使用 curl_getinfo 來判斷它是一個普通的 URL 還是重定向。

希望對您有所幫助

function getUrlContent($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
$data = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return ($httpcode>=200 && $httpcode<300) ? $data : false;
}

來源來自這個網站

http://softontherocks.blogspot.com/2014/11/descargar-el-contenido-de-una-url.html
nemetral
16 年前
快速提醒:如果您想使用 `curl_getinfo()` 搭配 `CURLINFO_HEADER_OUT` 選項來除錯您的 cURL 請求,您必須先在指定選項時加入 `curl_setopt($handle, CURLINFO_HEADER_OUT, true);`。
bg at enativ dot com
10 年前
即使設定了 `CURLOPT_FOLLOWLOCATION` 為 `false`,`curl_getinfo($ch)` 還是會回傳 `redirect_url`(如果有的話)。
我不知道為什麼文件中沒有提到這點⋯
Mark Evers
16 年前
該列表中缺少一個常數。如果設定了 `CURLOPT_FOLLOWLOCATION`,`CURLINFO_REDIRECT_COUNT` 將會提供您經歷的重新導向次數。
pluk77 at gmail dot com
9 個月前
即使將 `CURLOPT_SSL_VERIFYPEER` 設定為 `FALSE`,您仍然可以使用 `CURLINFO_SSL_VERIFYRESULT` 取得 SSL 驗證結果。

完整的結果代碼列表

0: 正常
1: 未指定的憑證驗證錯誤
2: 無法取得發行者憑證
3:無法取得憑證 CRL
4:無法解密憑證的簽章
5:無法解密 CRL 的簽章
6:無法解碼發行者公鑰
7:憑證簽章失敗
8:CRL 簽章失敗
9:憑證尚未生效
10:憑證已過期
11:CRL 尚未生效
12: CRL 已過期
13:憑證 notBefore 欄位的格式錯誤
14:憑證 notAfter 欄位的格式錯誤
15:CRL lastUpdate 欄位的格式錯誤
16:CRL nextUpdate 欄位的格式錯誤
17:記憶體不足
18: 自簽憑證
19: 憑證鏈中的自簽憑證
20:無法取得本地發行者憑證
21: 無法驗證第一個憑證
22:憑證鏈過長
23:憑證已撤銷
24: 發行者憑證沒有公開金鑰
25:超過路徑長度限制
26: 不合適的憑證用途
27:憑證不受信任
28:憑證遭拒
29:主體發行者不符
30:授權單位與主體金鑰識別碼不符
31:授權單位與發行者序號不符
32:金鑰用途不包含憑證簽署
33: 無法取得 CRL 發行者憑證
34: 未處理的關鍵擴充功能
35: 金鑰用途不包含 CRL 簽署
36: 未處理的關鍵 CRL 擴充功能
37: 無效的非 CA 憑證(具有 CA 標記)
38: 代理路徑長度限制已超出
39: 金鑰用途不包含數位簽章
40: 不允許代理憑證,請設定適當的旗標
41: 無效或不一致的憑證擴充功能
42: 無效或不一致的憑證策略擴充功能
43: 沒有明確的策略
44: 不同的 CRL 範圍
45: 不支援的擴充功能
46: RFC 3779 資源不是父資源的子集
47: 允許的子樹違規
48: 排除的子樹違規
49: 不支援名稱限制的最小值和最大值
50:應用程式驗證失敗
51: 不支援的名稱限制類型
52: 不支援或無效的名稱限制語法
53: 不支援或無效的名稱語法
54: CRL 路徑驗證錯誤
55: 路徑迴圈
56: Suite B:憑證版本無效
57: Suite B:無效的公開金鑰演算法
58: Suite B:無效的 ECC 曲線
59: Suite B:無效的簽章演算法
60: Suite B:此 LOS 不允許的曲線
61: Suite B:無法使用 P-256 簽署 P-384
62: 主機名稱不相符
63: 電子郵件地址不相符
64: IP 位址不相符
65: 沒有相符的 DANE TLSA 記錄
66: EE 憑證金鑰太弱
67: CA 憑證金鑰太弱
68: CA 簽章摘要演算法太弱
69: 無效的憑證驗證上下文
70: 發行者憑證查詢錯誤
71: 需要憑證透明度,但找不到有效的 SCT
72: 代理主體名稱違規
73: 需要 OCSP 驗證
74: OCSP 驗證失敗
75: OCSP 未知憑證
76: 找不到憑證簽章演算法
77: 主體簽章演算法和發行者公開金鑰演算法不相符
78: 憑證資訊簽章和簽章演算法不相符
79: 無效的 CA 憑證
80: 非 CA 憑證的路徑長度無效
81: 指定路徑長度但未使用金鑰用途 keyCertSign
82: 非 CA 憑證的金鑰用途 keyCertSign 無效
83: 簽發者名稱空白
84: 主旨名稱空白
85: 缺少授權金鑰識別碼 (Authority Key Identifier)
86: 缺少主旨金鑰識別碼 (Subject Key Identifier)
87: 主旨替代名稱 (Subject Alternative Name) 延伸欄位空白
89: CA 憑證的基本限制未標記為關鍵 (critical)
88: 主旨空白且主旨替代名稱延伸欄位未標記為關鍵
90: 授權金鑰識別碼標記為關鍵
91: 主旨金鑰識別碼標記為關鍵
92: CA 憑證不包含金鑰用途延伸欄位
93: 使用憑證延伸欄位至少需要 X509v3
94: 憑證公開金鑰具有明確的 ECC 參數
95: 原始公開金鑰不受信任,未設定任何受信任的金鑰

來源:https://github.com/openssl/openssl/blob/master/include/openssl/x509_vfy.h.in
https://github.com/openssl/openssl/blob/master/crypto/x509/x509_txt.c
c dot ball1729 at gmail dot com
1 年前
關於 $curl_info['header_size'] 的注意事項(回應上述範例)。

請注意,總大小包含任何由 CURLOPT_SUPPRESS_CONNECT_HEADERS 隱藏的已接收標頭大小(請參閱:https://curl.se/libcurl/c/CURLINFO_HEADER_SIZE.html),因此如果您使用代理伺服器,並且該代理伺服器新增了額外的標頭以及此選項,則 $curl_info['header_size'] 會根據 PHP 中可用的標頭提供錯誤的字串索引。也就是說,它會從回應的開頭開始計算,而不是回應的真正起始索引。
torres dot krys at gmail dot com
9 年前
如果您使用 curl 選項 CURLOPT_NOBODY = true 來測試遠端網址是否可用,任何網站都可能向您發送 http 代碼 400,例如 Cdiscount Wsdl

$ch = @curl_init($wsdl);

if($ch === false)
return false;

@curl_setopt($ch, CURLOPT_HEADER ,true); // 我們需要標頭
@curl_setopt($ch, CURLOPT_NOBODY ,true); // 不需要主體
@curl_setopt($ch, CURLOPT_RETURNTRANSFER ,true); // 擷取輸出(不要列印!)

@curl_exec($ch);

if(@curl_errno($ch)){ // 應該是 0
@curl_close($ch);
return false;
}

$code = @curl_getinfo($ch, CURLINFO_HTTP_CODE);

將 CURLOPT_NOBODY 修改為 false,發送的 http 代碼為 200,否則 http 代碼為 400 !!!
匿名
14 年前
主要文件忽略提及當設定 CURLINFO_HEADER_OUT 選項時,此函數返回的陣列將包含一個新的屬性 request_header,它是請求中發送的標頭字串。
Curly
9 年前
如果您在已傳遞給 curl_exec() 的控制代碼上呼叫 curl_reset(),然後在同一個控制代碼上執行 curl_getinfo(),您可能會期望得到與在 curl_init() 之後立即呼叫 curl_getinfo() 相同的結果。然而,事實並非如此。cURL 將返回先前執行的資料。如果您想要完全重置,您實際上需要取消設定 cURL 控制代碼並重新建立一個新的。
xggrquplbSa at seo-laboratory dot ru
4 個月前
如何學習唱歌和舞台表演:聲樂課程
聲樂老師 <a href=https://uroki-vocala-msk.ru/>https://uroki-vocala-msk.ru/</a>
To Top