PHP 的 cURL库快速入门文档
作者:Burak Guzel
原文链接:http://net.tutsplus.com/tutorials/php/techniques-and-resources-for-mastering-curl/
翻译:笨活儿
cURL 是一个利用 URL 语法规定来传输文件和数据的工具,支持很多协议,如 HTTP、FTP、TELNET 等。最爽的是,PHP 也支持 cURL 库。本文将介绍 cURL 的一些高级特性,以及在 PHP 中如何运用它。
为什么要用 cURL?
是的,我们可以通过其他办法获取网页内容。大多数时候,我因为想偷懒,都直接用简单的PHP函数:
12345 |
|
不过,这种做法缺乏灵活性和有效的错误处理。而且,你也不能用它完成一些高难度任务——比如处理coockies、验证、表单提交、文件上传等等。
基本结构
在学习更为复杂的功能之前,先来看一下在 PHP 中建立 cURL 请求的基本步骤:
- 初始化
- 设置变量
- 执行并获取结果
- 释放 cURL 句柄
12345678910111213 |
|
第二步(也就是 curl_setopt() )最为重要,一切玄妙均在此。有一长串 cURL 参数可供设置,它们能指定 URL 请求的各个细节。要一次性全部看完并理解可能比较困难,所以今天我们只试一下那些更常用也更有用的选项。
检查错误
你可以加一段检查错误的语句(虽然这并不是必需的):
123456 |
|
请注意,比较的时候我们用的是“=== FALSE”,而非“== FALSE”。因为我们得区分 空输出 和 布尔值 FALSE,后者才是真正的错误。
获取信息
这是另一个可选的设置项,能够在 cURL 执行后获取这一请求的有关信息:
12345 |
|
返回的数组中包括了以下信息:
“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” //上传内容的长度
“starttransfer_time” //开始传输的时间
“redirect_time”//重定向耗时
基于浏览器的重定向
在第一个例子中,我们将提供一段用于侦测服务器是否有基于浏览器的重定向的代码。例如,有些网站会根据是否是手机浏览器甚至用户来自哪个国家来重定向网页。
我们利用 CURLOPT_HTTPHEADER 选项来设定我们发送出的 HTTP 请求头信息(http headers),包括 user agent 信息和默认语言。然后我们来看看这些特定网站是否会把我们重定向到不同的URL。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
|
首先,我们建立一组需要测试的URL,接着指定一组需要测试的浏览器信息。最后通过循环测试各种URL和浏览器匹配可能产生的情况。
因为我们指定了cURL选项,所以返回的输出内容则只包括HTTP头信息(被存放于 $output 中)。利用一个简单的正则,我们检查这个头信息中是否包含了“Location:”字样。
运行这段代码应该会返回如下结果:
用POST方法发送数据
当发起 GET 请求时,数据可以通过“查询字串”(query string)传递给一个URL。例如,在google中搜索时,搜索关键即为 URL 的查询字串的一部分:
http://www.google.com/search?q=nettuts
这种情况下你可能并不需要 cURL 来模拟。把这个 URL 丢给“file_get_contents()”就能得到相同结果。
不过有一些 HTML 表单是用 POST 方法提交的。这种表单提交时,数据是通过 HTTP 请求体(request body) 发送,而不是查询字串。例如,当使用 CodeIgniter 论坛的表单,无论你输入什么关键字,总是被 POST 到如下页面:
http://codeigniter.com/forums/do_search/
你可以用 PHP 脚本来模拟这种 URL 请求。首先,新建一个可以接受并显示 POST 数据的文件,我们给它命名为post_output.php:
print_r($_POST);
接下来,写一段 PHP 脚本来执行 cURL 请求:
12345678910111213 |
|
执行代码后应该会得到以下结果:
这段脚本发送一个 POST 请求给 post_output.php ,这个页面 $_POST 变量并返回,我们利用 cURL 捕捉了这个输出。
文件上传
上传文件和前面的 POST 十分相似。因为所有的文件上传表单都是通过 POST 方法提交的。
首先新建一个接收文件的页面,命名为 upload_output.php:
print_r($_FILES);
以下是真正执行文件上传任务的脚本:
12345678910111213141516 |
|
如果你需要上传一个文件,只需要把文件路径像一个 post 变量一样传过去,不过记得在前面加上@符号。执行这段脚本应该会得到如下输出:
cURL批处理(multi cURL)
cURL 还有一个高级特性——批处理句柄(handle)。这一特性允许你同时或异步地打开多个URL连接。
下面是来自来自 php.net 的示例代码:
12345678910111213141516171819202122232425262728293031323334353637 |
|
这里要做的就是打开多个 cURL 句柄并指派给一个批处理句柄。然后你就只需在一个 while 循环里等它执行完毕。
这个示例中有两个主要循环。第一个 do-while 循环重复调用 curl_multi_exec() 。这个函数是无隔断(non-blocking)的,但会尽可能少地执行。它返回一个状态值,只要这个值等于常量 CURLM_CALL_MULTI_PERFORM ,就代表还有一些刻不容缓的工作要做(例如,把对应 URL 的 http 头信息发送出去)。也就是说,我们需要不断调用该函数,直到返回值发生改变。
而接下来的 while 循环,只在 $active 变量为 true 时继续。这一变量之前作为第二个参数传给了 curl_multi_exec() ,代表只要批处理句柄中是否还有活动连接。接着,我们调用 curl_multi_select() ,在活动连接(例如接受服务器响应)出现之前,它都是被“屏蔽”的。这个函数成功执行后,我们又会进入另一个 do-while 循环,继续下一条URL。
还是来看一看怎么把这一功能用到实处吧:
WordPress 连接检查器
想象一下你有一个文章数目庞大的博客,这些文章中包含了大量外部网站链接。一段时间之后,因为这样那样的原因,这些链接中相当数量都失效了。要么是被和谐了,要么是整个站点都被功夫网了…
我们下面建立一个脚本,分析所有这些链接,找出打不开或者 404 的网站/网页,并生成一个报告。
请注意,以下并不是一个真正可用的 WordPress 插件,仅仅是一段独立功能的脚本而已,仅供演示,谢谢。
好,开始吧。首先,从数据库中读取所有这些链接:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 |
|
我们首先配置好数据库,一系列要排除的域名($excluded_domains),以及最大并发连接数($max_connections)。然后,连接数据库,获取文章和包含的链接,把它们收集到一个数组中($url_list)。
下面的代码有点复杂了,因此我将一小步一小步地详细解释:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
|
下面解释一下以上代码。列表的序号对应着代码注释中的顺序数字。
- 新建一个批处理器。Created a multi handle.
- 稍后我们将创建一个把URL加入批处理器的函数 add_url_to_multi_handle() 。每当这个函数被调用,就有一个新url被加入批处理器。一开始,我们给批处理器添加了10个URL(这一数字由 $max_connections 所决定)。
- 运行 curl_multi_exec() 进行初始化工作是必须的,只要它返回 CURLM_CALL_MULTI_PERFORM 就还有事情要做。这么做主要是为了创建连接,它不会等待完整的URL响应。
- 只要批处理中还有活动连接主循环就会一直持续。
- curl_multi_select() 会一直等待,直到某个URL查询产生活动连接。
- cURL的活儿又来了,主要是获取响应数据。
- 检查各种信息。当一个URL请求完成时,会返回一个数组。
- 在返回的数组中有一个 cURL 句柄。我们利用其获取单个cURL请求的相应信息。
- 如果这是一个死链或者请求超时,不会返回http状态码。
- 如果这个页面找不到了,会返回404状态码。
- 其他情况我们都认为这个链接是可用的(当然,你也可以再检查一下500错误之类…)。
- 从该批次移除这个cURL句柄,因为它已经没有利用价值了,关了它!
- 很好,现在可以另外加一个URL进来了。再一次地,初始化工作又开始进行…
- 嗯,该干的都干了。关闭批处理器,生成报告。
- 回过头来看给批处理器添加新URL的函数。这个函数每调用一次,静态变量 $index 就递增一次,这样我们才能知道还剩多少URL没处理。
我把这个脚本在我的博客上跑了一遍(测试需要,有一些错误链接是故意加上的),结果如下:
另一些有用的cURL 选项
HTTP 认证
如果某个URL请求需要基于 HTTP 的身份验证,你可以使用下面的代码:
1234567891011121314 |
|
FTP 上传
PHP 自带有 FTP 类库, 但你也能用 cURL:
1234567891011121314151617 |
|
翻墙术
你可以用代理发起 cURL 请求:
12345678910 |
|
回调函数
可以在一个 URL 请求过程中,让 cURL 调用某指定的回调函数。例如,在内容或者响应下载的过程中立刻开始利用数据,而不用等到完全下载完。
12345678910 |
|
这个回调函数必须返回字串的长度,不然此功能将无法正常使用。
在 URL 响应接收的过程中,只要收到一个数据包,这个函数就会被调用。
小结
今天我们一起学习了 cURL 库的强大功能和灵活的扩展性。希望你喜欢。下一次要发起 URL 请求时,考虑下 cURL 吧!
转载于:https://www.cnblogs.com/17too/archive/2010/12/22/1913341.html
PHP 的 cURL库快速入门文档相关推荐
- GeoPandas官方快速入门文档(中文翻译版)
GeoPandas官方快速入门文档(中文翻译版) 原文链接>>Introduction to GeoPandas 点这里可以一键跑通>>GeoPandas 简介 GeoPand ...
- php基础 快速入门文档,快速入门 - Laravel 5.8 中文文档手册 - php中文网手册
Eloquent:入门 简介 Laravel 的 Eloquent ORM 提供了一个漂亮.简洁的 ActiveRecord 实现来和数据库交互.每个数据库表都有一个对应的「模型」用来与该表交互.你可 ...
- InstallSield更新包快速入门文档----感谢原作者ㄣ齊¨彡仯乄的无私提供
本文经原作者ㄣ齊¨彡仯乄特许授权于海洋女神发布,转载请务必注明出处与链接:原作者ㄣ齊¨彡仯乄和海洋女神保留对该文的一切法律许可下的权益:需要发布在盈利性报刊.网站等请与原作者ㄣ齊¨彡仯乄或海洋女神联系 ...
- Flutter网络请求库DIO入门文档(1),android开发网
}); response = await dio.post("http/test/upload", data: formData); //上传多个文件 formData = For ...
- Flutter网络请求库DIO入门文档,实战案例
var request = await httpClient.getUrl(Uri.parse(url)); var response = await request.close(); if (res ...
- jquery最快速入门文档
<!DOCTYPE html> jQuery 选择器 1. id $('#id') class <div class="c1"></div> $ ...
- Android入门文档
该文章为网络材料整理,部分内容经过重新编写. 一. 名词介绍 JDK:Java Development Kit Java 语言的软件开发工具包 JRE:Java Runtime Environment ...
- UniRx官方入门文档
UniRx 官方文档翻译 UniRx官方入门文档 UniRx入门系列一 UniRx入门系列二 UniRx入门系列三 UniRx入门系列四 UniRx入门系列五 UniRx 基于Unity的响应式编程框 ...
- CloudEvents 入门文档
CloudEvents 入门文档 - 1.0.3 版本 文档来自:GitHub CloudEvents 摘要 这份非技术规范文档用来为你提供关于 CloudEvents 规范的总体概览.它补充了 Cl ...
最新文章
- 树莓派安装docker
- 理解First Chance和Second Chance避免单步调试
- H5前端框架推荐合集 (转)
- srtvlet filter
- 随机生成1024个数,存入一段内存,用指针实现获取1024个数的最大数地址,最小数地址
- linux vim (your system doesn't appear to have the zip pgm)
- IPV4与IPV6的区别(史上最详细)
- 【Zookeeper】cnxn.saslServer is null cnxn object did not init its saslServer properly
- 七年也扶不起的苹果 Siri
- nodemcu固件编译
- 数据时代的来临,大数据价值主要体现在哪几个方面?
- deepin更新依赖错误_Ubuntu安装deepin-wine解决依赖问题
- 搞定签到码,一切皆可码!!!微信小程序篇
- C# 判断有向图是否存在环
- 敏捷开发实践经验分享
- 王道书 P360 T03(计数排序)
- RT-Thread 4.1.0 开启 PM 电源管理框架
- Tensorflow2.0 Resnet18与cifar100
- PLINK-GWAS学习3------数据质控之性别质控
- URULE规则引擎——决策树
热门文章
- HTTP MIME type
- Q767 重构字符串
- 火狐浏览器不执行alert的问题
- 【总结整理】JQuery基础学习---DOM篇
- Rhel7 Ldap为本地用户认证方式,设置域、服务器位置和下载key
- Autodesk Cloud Accelerator Program 开始报名
- libvirt-adabddad
- Linux 高可用(HA)集群之Pacemaker详解
- 实现一个包含Microsoft.Advertising和SmartMad广告控件的UserControl
- 基于【CentOS-7+ Ambari 2.7.0 + HDP 3.0】HAWQ数据仓库 使用之 gpfdist协议