CakeFest 2024: The Official CakePHP Conference

curl_getinfo

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

curl_getinfo获取一个cURL连接资源句柄的信息

说明

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

获取最后一次传输的相关信息。

参数

handle

curl_init() 返回的 cURL 句柄。

option

这个参数可能是以下常量之一:

选项 说明
CURLINFO_CAINFO 默认内置 CA 证书路径
CURLINFO_CAPATH 默认内置 CA 路径字符串
CURLINFO_EFFECTIVE_URL 最后一个有效的 URL
CURLINFO_HTTP_CODE 最后的响应代码。自 cURL 7.10.8 起,这是 CURLINFO_RESPONSE_CODE 的旧别名
CURLINFO_FILETIME 启用了 CURLOPT_FILETIME 后检索文档的远程时间;如果返回 -1,则文档的时间未知
CURLINFO_TOTAL_TIME 最后一次传输的总事务时间(以秒为单位)
CURLINFO_NAMELOOKUP_TIME 到名称解析完成所需的时间(以秒为单位)
CURLINFO_CONNECT_TIME 建立连接所需的时间(以秒为单位)
CURLINFO_PRETRANSFER_TIME 从启动到文件准备要传输所需的时间(以秒为单位)
CURLINFO_STARTTRANSFER_TIME 从启动到传输第一个字节之前所需的时间(以秒为单位)
CURLINFO_REDIRECT_COUNT 启用 CURLOPT_FOLLOWLOCATION 选项后的重定向次数
CURLINFO_REDIRECT_TIME 在启用 CURLOPT_FOLLOWLOCATION 选项后,最终事务开始之前所有重定向步骤的时间(以秒为单位)
CURLINFO_REDIRECT_URL 禁用 CURLOPT_FOLLOWLOCATION 选项:重定向 URL 在上次事务中找到,接下来应该手动请求。在启用 CURLOPT_FOLLOWLOCATION 选项的情况下,此值为空。在这种情况下,重定向的 URL 可以在 CURLINFO_EFFECTIVE_URL 中获取
CURLINFO_PRIMARY_IP 最近连接的 IP 地址
CURLINFO_PRIMARY_PORT 最近一次连接的目标端口
CURLINFO_LOCAL_IP 最近连接的本地(源)IP 地址
CURLINFO_LOCAL_PORT 最近连接的本地(源)端口
CURLINFO_SIZE_UPLOAD 上传的总字节数
CURLINFO_SIZE_DOWNLOAD 下载的总字节数
CURLINFO_SPEED_DOWNLOAD 平均下载速度
CURLINFO_SPEED_UPLOAD 平均上传速度
CURLINFO_HEADER_SIZE 检索到的所有 header 总大小
CURLINFO_HEADER_OUT 发送请求的字符串。为此,通过调用 curl_setopt()CURLINFO_HEADER_OUT 选项添加到句柄
CURLINFO_REFERER referrer header
CURLINFO_REQUEST_SIZE 已发出请求的总大小,当前仅针对 HTTP 请求
CURLINFO_RETRY_AFTER 来自 Retry-After: header 的信息,如果没有有效的 header,则为 0。
CURLINFO_SSL_VERIFYRESULT 通过设置 CURLOPT_SSL_VERIFYPEER 请求的 SSL 认证验证结果
CURLINFO_CONTENT_LENGTH_DOWNLOAD Content-Length: 字段中读取的下载内容长度
CURLINFO_CONTENT_LENGTH_UPLOAD 指定上传大小
CURLINFO_CONTENT_TYPE Content-Type: 所请求文档的类型。NULL 表示服务器没有发送有效的 Content-Type: header
CURLINFO_PRIVATE 与此 cURL 句柄关联的私有数据,之前使用 curl_setopt()CURLOPT_PRIVATE 选项设置
CURLINFO_PROXY_ERROR 当最近的传输返回 CURLE_PROXY 错误时,会返回详细的(SOCKS)代理错误代码。返回的值将恰好是 CURLPX_* 值之一。如果没有响应代码可用,错误代码将是 CURLPX_OK
CURLINFO_RESPONSE_CODE 最后的响应代码
CURLINFO_HTTP_CONNECTCODE CONNECT 响应代码
CURLINFO_HTTPAUTH_AVAIL 位掩码表示根据先前响应可用的身份验证方法
CURLINFO_PROXYAUTH_AVAIL 位掩码表示根据先前响应可用的代理身份验证方法
CURLINFO_OS_ERRNO 来自连接失败的 Errno。该数字是操作系统和系统特定的。
CURLINFO_NUM_CONNECTS curl 为实现先前的传输所必须创建的连接数
CURLINFO_SSL_ENGINES 支持 OpenSSL 加密引擎
CURLINFO_COOKIELIST 所有已知的 cookie
CURLINFO_FTP_ENTRY_PATH FTP 服务器中的入口路径
CURLINFO_APPCONNECT_TIME 从开始到 SSL/SSH 完成与远程主机的连接/握手所花费的时间(以秒为单位)
CURLINFO_CERTINFO TLS 证书链
CURLINFO_CONDITION_UNMET 未满足时间条件的信息
CURLINFO_RTSP_CLIENT_CSEQ 下一个 RTSP 客户端 CSeq
CURLINFO_RTSP_CSEQ_RECV 最近检索到的 CSeq
CURLINFO_RTSP_SERVER_CSEQ 下一个 RTSP 服务器端 CSeq
CURLINFO_RTSP_SESSION_ID RTSP 会话 ID
CURLINFO_CONTENT_LENGTH_DOWNLOAD_T 下载的内容长度。此值从 Content-Length: 字段读取。如果大小未知则为 -1
CURLINFO_CONTENT_LENGTH_UPLOAD_T 上传的指定大小。如果未知则为 -1
CURLINFO_HTTP_VERSION 返回最后一次 HTTP 连接中使用的版本。返回值将是定义的 CURL_HTTP_VERSION_* 常量之一,如果无法确定版本,则返回 0。
CURLINFO_PROTOCOL 在最后一个 HTTP 连接中使用的协议。返回值将会是 CURLPROTO_* 中的一个值
CURLINFO_PROXY_SSL_VERIFYRESULT 请求的证书验证结果(使用 CURLOPT_PROXY_SSL_VERIFYPEER 选项)。仅用于 HTTPS 代理
CURLINFO_SCHEME 最近连接使用的 URL 协议
CURLINFO_SIZE_DOWNLOAD_T 已下载的总字节数。此数值仅针对最新的传输,并且在每次新的传输时都将会重置
CURLINFO_SIZE_UPLOAD_T 上传的总字节数
CURLINFO_SPEED_DOWNLOAD_T curl 测量的完整下载速度的平均值,以字节/秒为单位
CURLINFO_SPEED_UPLOAD_T curl 测量的完整上传速度的平均值,以字节/秒为单位
CURLINFO_APPCONNECT_TIME_T 从开始到与远程主机 SSL/SSH 连接/握手完成所经过的时间,以微秒为单位
CURLINFO_CONNECT_TIME_T 从开始到与远程主机(或代理)建立连接完成所经过的总时间,以微秒为单位
CURLINFO_FILETIME_T 检索的文档的远程时间(Unix 时间戳),是 CURLINFO_FILETIME 的替代值,允许具有 32 bit 变量的系统提取超出 32 bit 时间戳范围之外的日期
CURLINFO_NAMELOOKUP_TIME_T 从开始到名称解析完成的时间(以微秒为单位)
CURLINFO_PRETRANSFER_TIME_T 从开始到文件传输即将开始的时间,以微秒为单位
CURLINFO_REDIRECT_TIME_T 在最终事务开始之前,所有重定向步骤(包括名称查找、连接、预传输和传输)所花费的总时间,以微秒为单位。
CURLINFO_STARTTRANSFER_TIME_T 从开始到接收到第一个字节所花费的时间(以微秒为单位)
CURLINFO_TOTAL_TIME_T 上次传输的总时间(以微秒为单位),包括名称解析、TCP 连接等。

返回值

如果指定 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 后才会设置)
注意,私有数据不包含在关联数组中,必须使用 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
'Took ', $info['total_time'], ' seconds to send a request to ', $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: # OK
break;
default:
echo
'Unexpected HTTP code: ', $http_code, "\n";
}
}

// 关闭句柄
curl_close($ch);
?>

注释

注意:

如果重新使用句柄,则保留此函数收集的信息。这意味着除非此函数在内部覆盖统计信息,否则将返回以前的信息。

add a note

User Contributed Notes 15 notes

up
57
ssttoo at hotmail dot com
19 years ago
Here are the response codes ready for pasting in an ini-style file. Can be used to provide more descriptive message, corresponding to 'http_code' index of the arrray returned by curl_getinfo().
These are taken from the W3 consortium HTTP/1.1: Status Code Definitions, found at
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

[Informational 1xx]
100="Continue"
101="Switching Protocols"

[Successful 2xx]
200="OK"
201="Created"
202="Accepted"
203="Non-Authoritative Information"
204="No Content"
205="Reset Content"
206="Partial Content"

[Redirection 3xx]
300="Multiple Choices"
301="Moved Permanently"
302="Found"
303="See Other"
304="Not Modified"
305="Use Proxy"
306="(Unused)"
307="Temporary Redirect"

[Client Error 4xx]
400="Bad Request"
401="Unauthorized"
402="Payment Required"
403="Forbidden"
404="Not Found"
405="Method Not Allowed"
406="Not Acceptable"
407="Proxy Authentication Required"
408="Request Timeout"
409="Conflict"
410="Gone"
411="Length Required"
412="Precondition Failed"
413="Request Entity Too Large"
414="Request-URI Too Long"
415="Unsupported Media Type"
416="Requested Range Not Satisfiable"
417="Expectation Failed"

[Server Error 5xx]
500="Internal Server Error"
501="Not Implemented"
502="Bad Gateway"
503="Service Unavailable"
504="Gateway Timeout"
505="HTTP Version Not Supported"

And an example usage:
<?php
$ch
= curl_init(); // create cURL handle (ch)
if (!$ch) {
die(
"Couldn't initialize a cURL handle");
}
// set some cURL options
$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);

// execute
$ret = curl_exec($ch);

if (empty(
$ret)) {
// some kind of an error happened
die(curl_error($ch));
curl_close($ch); // close cURL handler
} else {
$info = curl_getinfo($ch);
curl_close($ch); // close cURL handler

if (empty($info['http_code'])) {
die(
"No HTTP code was returned");
} else {
// load the HTTP codes
$http_codes = parse_ini_file("path/to/the/ini/file/I/pasted/above");

// echo results
echo "The server responded: <br />";
echo
$info['http_code'] . " " . $http_codes[$info['http_code']];
}

}
?>
up
22
vince
13 years ago
CURLINFO_HTTP_CODE does not return a string, as the docs say, but rather an integer.

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

returns

"CURLINFO_HTTP_CODE returns an integer."
up
7
public-mail at alekciy dot ru
8 years ago
Note, header_size include "\r\n\r\n". So if you use CURLOPT_FOLLOWLOCATION>0, CURLOPT_HEADER=true, CURLOPT_RETURNTRANSFER=true right way splite 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);
up
17
nikita dot bulatenko at gmail dot com
11 years ago
CURLINFO_SSL_VERIFYRESULT error codes:
0: ok the operation was successful.
2 : unable to get issuer certificate
3: unable to get certificate CRL
4: unable to decrypt certificate's signature
5: unable to decrypt CRL's signature
6: unable to decode issuer public key
7: certificate signature failure
8: CRL signature failure
9: certificate is not yet valid
10: certificate has expired
11: CRL is not yet valid
12:CRL has expired
13: format error in certificate's notBefore field
14: format error in certificate's notAfter field
15: format error in CRL's lastUpdate field
16: format error in CRL's nextUpdate field
17: out of memory
18: self signed certificate
19: self signed certificate in certificate chain
20: unable to get local issuer certificate
21:unable to verify the first certificate
22: certificate chain too long
23: certificate revoked
24: invalid CA certificate
25: path length constraint exceeded
26: unsupported certificate purpose
27: certificate not trusted
28: certificate rejected
29: subject issuer mismatch
30: authority and subject key identifier mismatch
31: authority and issuer serial number mismatch
32: key usage does not include certificate signing
50: application verification failure
details at http://www.openssl.org/docs/apps/verify.html#VERIFY_OPERATION
up
5
qrworld.net
9 years ago
Here you have a function that I use to get the content of a URL using cURL. This uses curl_getinfo to know if it is a regular URL or maybe a redirection.

I hope it would be useful for you:

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

The source comes from this website:

http://softontherocks.blogspot.com/2014/11/descargar-el-contenido-de-una-url.html
up
7
nemetral
15 years ago
Just a quick note: if you want to use curl_getinfo() with option CURLINFO_HEADER_OUT in order to debug your cURL request, you must add curl_setopt($handle, CURLINFO_HEADER_OUT, true); first while specifying the options.
up
3
bg at enativ dot com
10 years ago
curl_getinfo($ch) will also return 'redirect_url' if there is one (even if CURLOPT_FOLLOWLOCATION set to false).
I don't know why it's not in the doc..
up
2
Mark Evers
16 years ago
There is a constant missing from that list. CURLINFO_REDIRECT_COUNT will give you the number of redirects it went through if CURLOPT_FOLLOWLOCATION was set.
up
0
wow_boost_xkOl
4 days ago
Game-Changing Boost: How WoW Boosting Services Work Wonders
wow boosts <a href=http://wow-boost1.com/>http://wow-boost1.com/</a> .
up
0
pluk77 at gmail dot com
24 days ago
You can still get the SSL verification result using CURLINFO_SSL_VERIFYRESULT when setting CURLOPT_SSL_VERIFYPEER to FALSE.

Full list of result codes:

0: ok
1: unspecified certificate verification error
2: unable to get issuer certificate
3: unable to get certificate CRL
4: unable to decrypt certificate's signature
5: unable to decrypt CRL's signature
6: unable to decode issuer public key
7: certificate signature failure
8: CRL signature failure
9: certificate is not yet valid
10: certificate has expired
11: CRL is not yet valid
12: CRL has expired
13: format error in certificate's notBefore field
14: format error in certificate's notAfter field
15: format error in CRL's lastUpdate field
16: format error in CRL's nextUpdate field
17: out of memory
18: self-signed certificate
19: self-signed certificate in certificate chain
20: unable to get local issuer certificate
21: unable to verify the first certificate
22: certificate chain too long
23: certificate revoked
24: issuer certificate doesn't have a public key
25: path length constraint exceeded
26: unsuitable certificate purpose
27: certificate not trusted
28: certificate rejected
29: subject issuer mismatch
30: authority and subject key identifier mismatch
31: authority and issuer serial number mismatch
32: key usage does not include certificate signing
33: unable to get CRL issuer certificate
34: unhandled critical extension
35: key usage does not include CRL signing
36: unhandled critical CRL extension
37: invalid non-CA certificate (has CA markings)
38: proxy path length constraint exceeded
39: key usage does not include digital signature
40: proxy certificates not allowed, please set the appropriate flag
41: invalid or inconsistent certificate extension
42: invalid or inconsistent certificate policy extension
43: no explicit policy
44: different CRL scope
45: unsupported extension feature
46: RFC 3779 resource not subset of parent's resources
47: permitted subtree violation
48: excluded subtree violation
49: name constraints minimum and maximum not supported
50: application verification failure
51: unsupported name constraint type
52: unsupported or invalid name constraint syntax
53: unsupported or invalid name syntax
54: CRL path validation error
55: path loop
56: Suite B: certificate version invalid
57: Suite B: invalid public key algorithm
58: Suite B: invalid ECC curve
59: Suite B: invalid signature algorithm
60: Suite B: curve not allowed for this LOS
61: Suite B: cannot sign P-384 with P-256
62: hostname mismatch
63: email address mismatch
64: IP address mismatch
65: no matching DANE TLSA records
66: EE certificate key too weak
67: CA certificate key too weak
68: CA signature digest algorithm too weak
69: invalid certificate verification context
70: issuer certificate lookup error
71: Certificate Transparency required, but no valid SCTs found
72: proxy subject name violation
73: OCSP verification needed
74: OCSP verification failed
75: OCSP unknown cert
76: Cannot find certificate signature algorithm
77: subject signature algorithm and issuer public key algorithm mismatch
78: cert info signature and signature algorithm mismatch
79: invalid CA certificate
80: Path length invalid for non-CA cert
81: Path length given without key usage keyCertSign
82: Key usage keyCertSign invalid for non-CA cert
83: Issuer name empty
84: Subject name empty
85: Missing Authority Key Identifier
86: Missing Subject Key Identifier
87: Empty Subject Alternative Name extension
89: Basic Constraints of CA cert not marked critical
88: Subject empty and Subject Alt Name extension not critical
90: Authority Key Identifier marked critical
91: Subject Key Identifier marked critical
92: CA cert does not include key usage extension
93: Using cert extension requires at least X509v3
94: Certificate public key has explicit ECC parameters
95: Raw public key untrusted, no trusted keys configured

source: 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
up
0
c dot ball1729 at gmail dot com
9 months ago
A note about $curl_info['header_size'] (in response to the example above).

Note that the total includes the size of any received headers suppressed by CURLOPT_SUPPRESS_CONNECT_HEADERS (see: https://curl.se/libcurl/c/CURLINFO_HEADER_SIZE.html) so if you are using a proxy which adds additional headers along with this option, $curl_info['header_size'] will give you the wrong string index based on the headers available in PHP. i.e., it will eat in to the start of the response instead of being the index of the beginning of the response.
up
0
torres dot krys at gmail dot com
8 years ago
If you use curl option CURLOPT_NOBODY = true to test if distant url is available, any sites can send you an http code 400 like Cdiscount Wsdl :

$ch = @curl_init($wsdl);

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

@curl_setopt($ch, CURLOPT_HEADER ,true); // we want headers
@curl_setopt($ch, CURLOPT_NOBODY ,true); // dont need body
@curl_setopt($ch, CURLOPT_RETURNTRANSFER ,true); // catch output (do NOT print!)

@curl_exec($ch);

if(@curl_errno($ch)){ // should be 0
@curl_close($ch);
return false;
}

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

Modifying CURLOPT_NOBODY to false, http code sent is 200 otherwise http code is 400 !!!
up
0
Anonymous
13 years ago
The main doc neglects to mention that when the CURLINFO_HEADER_OUT option is set the array returned by this function will included a new property, request_header, that is a string of the headers sent in the request.
up
-2
Curly
8 years ago
If you call curl_reset() on a handle that has already been passed to curl_exec(), and then perform a curl_getinfo() on the same handle, you may expect that you get the same result as if you called curl_getinfo() immediately after curl_init(). This is not the case, however. cURL will return the data from the previous execution. If you want to completely reset you actually need to unset the cURL handle and recreate a new one.
up
-15
luiheidsgoeroe at hotmail dot com
16 years ago
Keep in mind that for CURLOPT_RETURNTRANSFER it has to be set with curl_setopt() before execution:

This doesn't work:
<?php
$ch
= curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
var_dump(curl_getinfo($ch,CURLINFO_HEADER_OUT));
?>

This works:
<?php
$ch
= curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_exec($ch);
var_dump(curl_getinfo($ch,CURLINFO_HEADER_OUT));
?>
To Top