简介
在PHP中处理远程内容获取时,简单场景可以使用file_get_contents函数,但遇到复杂的HTTP POST、HTTP PUT、FTP 上传等操作时,我们需要更强大的工具。PHP提供的cURL扩展正好满足这些需求,以下是官方文档的介绍:
PHP支持的由Daniel Stenberg创建的libcurl库允许你与各种的服务器使用各种类型的协议进行连接和通讯。libcurl目前支持http、https、ftp、gopher、telnet、dict、file和ldap协议。libcurl同时也支持HTTPS认证、HTTP POST、HTTP PUT、FTP 上传(这个也能通过PHP的FTP扩展完成)、HTTP 基于表单的上传、代理、cookies和用户名+密码的认证。
cURL常量与配置选项
cURL提供了大量配置选项,下面将根据不同类型进行分类介绍:
1. 常用布尔值选项
CURLOPT_AUTOREFERER :当返回的信息头含有转向信息时,自动设置前向连接
CURLOPT_BINARYTRANSFER :在使用CURLOPT_RETURNTRANSFER时,返回原始的输出
CURLOPT_COOKIESESSION :标志为新的cookie会话,忽略之前设置的cookie会话
CURLOPT_CRLF :将Unix系统的换行符转换为Dos换行符
CURLOPT_DNS_USE_GLOBAL_CACHE :使用全局的DNS缓存
CURLOPT_FAILONERROR :忽略返回错误
CURLOPT_FILETIME :获取请求文档的修改日期,该日期可以用curl_getinfo()获取
CURLOPT_FOLLOWLOCATION :紧随服务器返回的所有重定向信息
CURLOPT_FORBID_REUSE :当进程处理完毕后强制关闭会话,不再缓存供重用
CURLOPT_FRESH_CONNECT :强制建立一个新的会话,而不是重用缓存的会话
CURLOPT_HEADER :在返回的输出中包含响应头信息
CURLOPT_HTTPGET :设置HTTP请求方式为GET
CURLOPT_HTTPPROXYTUNNEL :经由一个HTTP代理建立连接
CURLOPT_NOBODY :返回的输出中不包含文档信息
CURLOPT_NOPROGRESS :禁止进程级别传输,PHP自动设为真
CURLOPT_NOSIGNAL :忽略所有发往PHP的信息
CURLOPT_POST :设置POST方式提交数据,POST格式为application/x-www-form-urlencoded
CURLOPT_PUTTRUE :设置PUT方式上传文件,同时设置CURLOPT_INFILE和CURLOPT_INFILESIZE
CURLOPT_RETURNTRANSFER :返回字符串,而不是调用curl_exec()后直接输出
CURLOPT_SSL_VERIFYPEER :SSL验证开启
CURLOPT_UNRESTRICTED_AUTH :一直链接后面附加用户名和密码,同时设置CURLOPT_FOLLOWLOCATION
CURLOPT_UPLOAD :准备上传
2. 整数值选项
CURLOPT_BUFFERSIZE :缓存大小
CURLOPT_CONNECTTIMEOUT :连接时间设置,默认0为无限制
CURLOPT_DNS_CACHE_TIMEOUT :内存中保存DNS信息的时间,默认2分钟
CURLOPT_INFILESIZE :上传至远程站点的文件尺寸
CURLOPT_LOW_SPEED_LIMIT :传输最低速度限制
CURLOPT_LOW_SPEED_TIME :传输时间限制
CURLOPT_MAXCONNECTS :最大持久连接数
CURLOPT_MAXREDIRS :最大转向数
CURLOPT_PORT :连接端口
CURLOPT_PROXYAUTH :代理服务器验证方式
CURLOPT_PROXYPORT :代理服务器端口
CURLOPT_PROXYTYPE :代理服务器类型
CURLOPT_TIMEOUT :CURL函数的最大执行时间
3. 字符串选项
CURLOPT_COOKIE :HTTP头中set-cookie中的cookie信息
CURLOPT_COOKIEFILE :包含cookie信息的文件,cookie文件的格式可以是Netscape格式,或者只是HTTP头的格式
CURLOPT_COOKIEJAR :连接结束后保存cookie信息的文件
CURLOPT_CUSTOMREQUEST :自定义请求头,使用相对地址
CURLOPT_ENCODING :HTTP请求头中Accept-Encoding的值
CURLOPT_POSTFIELDS :POST格式提交的数据内容(也可以是数组)
CURLOPT_PROXY :代理通道
CURLOPT_PROXYUSERPWD :代理认证用户名和密码
CURLOPT_RANGE :返回数据的范围,以字节计算
CURLOPT_REFERER :前向链接
CURLOPT_URL :要连接的URL地址,可以在curl_init()中设置
CURLOPT_USERAGENT :HTTP头中User-Agent的值
CURLOPT_USERPWD :连接中使用的验证信息
4. 数组选项
CURLOPT_HTTP200ALIASES:200响应码数组,数组中的响应码被认为是正确的响应
CURLOPT_HTTPHEADER:自定义请求头信息
5. 流句柄选项
CURLOPT_FILE:传输要写入的文件句柄,默认是标准输出
CURLOPT_INFILE:传输要读取的文件句柄
CURLOPT_STDERR:作为标准错误输出的一个替换选项
CURLOPT_WRITEHEADER:传输头信息要写入的文件
6. 回调函数选项
CURLOPT_HEADERFUNCTION:拥有两个参数的回调函数,第一个参数是会话句柄,第二参数是HTTP响应头信息的字符串。响应头信息按行返回。设置返回值为字符串长度。
CURLOPT_READFUNCTION:拥有两个参数的回调函数,第一个参数是会话句柄,第二参数是HTTP响应内容。自行处理返回的数据。返回值为数据尺寸。
CURLOPT_WRITEFUNCTION:拥有两个参数的回调函数,第一个参数是会话句柄,第二参数是HTTP响应数据。自行处理响应数据。响应数据是整个字符串。设置返回值为字符串长度。
7. curl_getinfo中使用的常量
CURLINFO_EFFECTIVE_URL - 最后一个有效的URL地址
CURLINFO_HTTP_CODE - 最后一个收到的HTTP代码
CURLINFO_FILETIME - 远程获取文档的时间,如果无法获取,则返回值为"-1"
CURLINFO_TOTAL_TIME - 最后一次传输所消耗的时间
CURLINFO_NAMELOOKUP_TIME - 名称解析所消耗的时间
CURLINFO_CONNECT_TIME - 建立连接所消耗的时间
CURLINFO_PRETRANSFER_TIME - 从建立连接到准备传输所使用的时间
CURLINFO_STARTTRANSFER_TIME - 从建立连接到传输开始所使用的时间
CURLINFO_REDIRECT_TIME - 在事务传输开始前重定向所使用的时间
CURLINFO_SIZE_UPLOAD - 上传数据量的总值
CURLINFO_SIZE_DOWNLOAD - 下载数据量的总值
CURLINFO_SPEED_DOWNLOAD - 平均下载速度
CURLINFO_SPEED_UPLOAD - 平均上传速度
CURLINFO_HEADER_SIZE - header部分的大小
CURLINFO_HEADER_OUT - 发送请求的字符串
CURLINFO_REQUEST_SIZE - 在HTTP请求中有问题的请求的大小
CURLINFO_SSL_VERIFYRESULT - 通过设置CURLOPT_SSL_VERIFYPEER返回的SSL证书验证请求的结果
CURLINFO_CONTENT_LENGTH_DOWNLOAD - 从Content-Length: field中读取的下载内容长度
CURLINFO_CONTENT_LENGTH_UPLOAD - 上传内容大小的说明
CURLINFO_CONTENT_TYPE - 下载内容的Content-Type:值,NULL表示服务器没有发送有效的Content-Type: header
cURL 函数列表
PHP提供了一系列操作cURL的函数,以下是常用的cURL函数:
void curl_close ( resource $ch ) — 关闭一个cURL会话并且释放所有资源。cURL句柄ch 也会被释放。
resource curl_copy_handle ( resource $ch ) — 复制一个cURL句柄和它的所有选项(保持相同的选项)。
int curl_errno ( resource $ch ) — 返回最后一次的错误号。
string curl_error ( resource $ch ) — 返回一个保护当前会话最近一次错误的字符串。
string curl_escape ( resource $ch , string $str ) — 该函数使用 URL 根据» RFC 3986编码给定的字符串。
mixed curl_exec ( resource $ch ) — 执行一个cURL会话(这个函数应该在初始化一个cURL会话并且全部的选项都被设置后被调用)。
mixed curl_file_create(string $filename[, string $mimetype][,string $postname]) — 创建一个 CURLFile 对象。
mixed curl_getinfo ( resource $ch [, int $opt = 0 ] ) — 获取一个cURL连接资源句柄的信息。
resource curl_init ([ string $url = NULL ] ) — 初始化一个cURL会话,供curl_setopt(), curl_exec()和curl_close() 函数使用。
更多函数包括多句柄操作、共享句柄等,可以参考PHP官方文档获取完整列表。
实战应用场景
1. 构造一个简单的GET请求
以下代码展示如何使用cURL抓取网页内容:
⚠️ 注意:使用cURL进行网络请求时应注意超时设置,避免长时间阻塞PHP进程。
2. 构造一个简单的POST请求
POST请求常用于表单提交和API调用,下面是一个提交数据的例子:
运行结果:
3. HTTP 认证连接
某些API需要基本认证(Basic Authentication)才能访问,可以这样实现:
返回结果:
4. Cookie操作与保存
在Web应用中,Cookie处理是很常见的需求,以下展示如何使用cURL操作Cookie:
执行后,在脚本运行目录会生成cookies.log文件,内容格式如下:
5. 文件下载功能
cURL可以很方便地实现文件下载功能:
💡 上述代码执行后,将在代码目录下载并保存一个名为down.png的图片文件。
实现原理:自定义cURL类
为了简化cURL的使用,我们可以封装一个支持链式调用的cURL类,提供更友好的接口。
使用示例
实现代码
下面是一个支持链式调用的cURL类实现:
其他事项
在使用PHP cURL时,应遵循以下最佳实践:
- 始终关闭cURL连接:使用
curl_close()释放资源 - 设置超时参数:防止请求阻塞PHP进程
- 错误处理:使用
curl_errno()和curl_error()检查错误 - 复用cURL句柄:对于多次请求,可复用句柄提高性能
- 安全考虑:对于HTTPS请求,根据需要配置SSL验证选项