cURL 是一个利用URL语法规定来传输文件和数据的工具,支持很多协议和选项,如HTTP、FTP、TELNET等,能提供 URL 请求相关的各种细节信息。最爽的是,PHP 也支持 cURL 库。
本文将介绍 cURL 的一些高级特性,以及在 PHP 中如何运用它。
1 为什么要用cURL?
是的,我们可以通过其他办法获取网页内容。大多数时候,我因为想偷懒,都直接用简单的 PHP 的 file_get_contents() 函数:
$content = file_get_contents("http://www.awaimai.com"); $lines = file("http://www.awaimai.com"); readfile(http://www.awaimai.com);
不过,这种做法缺乏灵活性和有效的错误处理。而且,你也不能用它完成一些高难度任务,比如处理:coockies、验证、表单提交、文件上传等等。
2 启用cURL
首先,我们得先要确定 PHP 是否开启了这个库,你可以通过使用phpinfo()
函数来得到这一信息。如果在网页上看到下面的输出,那么表示 cURL 库已开启。
如果 curl 没有开启,那么就需要开启这个库。如果是在Windows平台下,那么非常简单,你需要改一改 php.ini
文件的设置,找到 php_curl.dll
,并取消前面的分号注释就行了。如下所示:
# 取消下面的注释 extension=php_curl.dll
如果是 Linux 服务器,需要重新编译 PHP ,编译时在configure
命令上加上--with-curl
参数。
3 基本结构
在学习更为复杂的功能之前,先来看一下在 PHP 中建立 cURL 请求的基本步骤:
- 初始化
- 设置选项
- 执行并获取结果
- 释放cURL句柄
实现代码如下:
// 1. 初始化 $ch = curl_init(); // 2. 设置选项 curl_setopt($ch, CURLOPT_URL, "http://www.awaimai.com"); // 设置要抓取的页面地址 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 抓取结果直接返回(如果为0,则直接输出内容到页面) curl_setopt($ch, CURLOPT_HEADER, 0); // 不需要页面的HTTP头 // 3. 执行并获取HTML文档内容,可用echo输出内容 $output = curl_exec($ch); // 4. 释放curl句柄 curl_close($ch);
第二步(也就是 curl_setopt()
)最为重要,一切玄妙均在此。有一长串cURL参数可供设置,它们能指定 URL 请求的各个细节。要一次性全部看完并理解可能比较困难,所以今天我们只试一下那些更常用也更有用的选项。
4 检查错误
你可以在 cur_exec()
后加一段检查错误的语句(虽然这并不是必需的):
$output = curl_exec($ch); if ($output === FALSE) { echo "cURL Error: " . curl_error($ch); }
请注意,比较的时候我们用的是=== FALSE
,而非== FALSE
。因为我们得区分空输出
和布尔值FALSE
,后者才是真正的错误。
5 获取信息
利用curl_getinfo()
能够在 cURL 执行后获取请求的有关信息,当然,这也是一个可选的设置项,:
curl_exec($ch); $info = curl_getinfo($ch); echo '获取'. $info['url'] . '耗时'. $info['total_time'] . '秒';
返回的数组中包括了以下信息:
- url //资源网络地址
- content_type //内容编码
- http_code //HTTP状态码
- header_size //header的大小
- request_size //请求的大小
- filetime //文件创建时间
- ssl_verify_result //SSL验证结果
- redirect_count //跳转技术
- total_time //总耗时
- namelookup_time //DNS查询耗时
- connect_time //等待连接耗时
- pretransfer_time //传输前准备耗时
- size_upload //上传数据的大小
- size_download //下载数据的大小
- speed_download //下载速度
- speed_upload //上传速度
- download_content_length //下载内容的长度
- upload_content_length //上传内