cURL库的强大功能和灵活的扩展性

上传人:ba****u 文档编号:169611585 上传时间:2022-11-16 格式:DOCX 页数:11 大小:27.65KB
收藏 版权申诉 举报 下载
cURL库的强大功能和灵活的扩展性_第1页
第1页 / 共11页
cURL库的强大功能和灵活的扩展性_第2页
第2页 / 共11页
cURL库的强大功能和灵活的扩展性_第3页
第3页 / 共11页
资源描述:

《cURL库的强大功能和灵活的扩展性》由会员分享,可在线阅读,更多相关《cURL库的强大功能和灵活的扩展性(11页珍藏版)》请在装配图网上搜索。

1、cURL 库的强大功能和灵活的扩展性cURL是一个利用URL语法规定来传输文件和数据的工具,支持很多协议,如HTTP、FTP、 TELNET等。最爽的是,PHP也支持cURL库。本文将介绍cURL的一些高级特性,以及 在 PHP 中如何运用它。为什么要用 cURL?是的,我们可以通过其他办法获取网页内容。大多数时候,我因为想偷懒,都直接用简单的 PHP 函数:$content = file_get_contents();/ or$lines = file();/ or readfile(); 不过,这种做法缺乏灵活性和有效的错误处理。而且,你也不能用它完成一些高难度任务比如处理coockies

2、、验证、表单提交、文件上传等等。引用:cURL是一种功能强大的库,支持很多不同的协议、选项,能提供URL请求相关的各种细 节信息。基本结构在学习更为复杂的功能之前,先来看一下在PHP中建立cURL请求的基本步骤:初始化 设置变量 执行并获取结果释放cURL句柄/ 1. 初始化$ch = curl_init();/ 2. 设置选项,包括 URL curl_setopt($ch, CURLOPT_URL, );curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_HEADER, 0);/ 3.执行并获取HTML文档

3、内容$output = curl_exec($ch);/ 4. 释放 curl 句柄 curl_close($ch);第二步(也就是 curl_setopt() )最为重要,一切玄妙均在此。有一长串 cURL 参数可供设 置,它们能指定URL请求的各个细节。要一次性全部看完并理解可能比较困难,所以今天 我们只试一下那些更常用也更有用的选项。检查错误 你可以加一段检查错误的语句(虽然这并不是必需的):/ .$output = curl_exec($ch); if ($output = FALSE) echo cURL Error: . curl_error($ch);/ .请注意,比较的时候我们

4、用的是“=FALSE”,而非“=FALSE”。因为我们得区分空输 出和布尔值FALSE,后者才是真正的错误。获取信息这是另一个可选的设置项,能够在cURL执行后获取这一请求的有关信息:/ . curl_exec($ch);$info = curl_getinfo($ch);echo 获取. $infourl . 耗时. $infototal_time . 秒;/ . 返回的数组中包括了以下信息:“ url” /资源网络地址“ content_type” /内容编码“http_code” /HTTP 状态码“ header_size” /header 的大小“request_size” /请求的

5、大小“ 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” /下载内容的长度“

6、 upload_content_length” /上传内容的长度“starttransfer_time” /开始传输的时间“ redirect_time” /重定向耗时 基于浏览器的重定向 在第一个例子中,我们将提供一段用于侦测服务器是否有基于浏览器的重定向的代码。例如, 有些网站会根据是否是手机浏览器甚至用户来自哪个国家来重定向网页。我们利用CURLOPT_HTTPHEADER选项来设定我们发送出的HTTP请求头信息(http headers),包括user agent信息和默认语言。然后我们来看看这些特定网站是否会把我们重 定向到不同的 URL。/ 测试用的 URL$urls = arra

7、y(, );/ 测试用的浏览器信息$browsers = array(standard = array (user_agent = Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 3.5.30729),language = en-us,en;q=0.5),iphone = array (user_agent = Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHT

8、ML, like Gecko) Version/3.0 Mobile/1A537a Safari/419.3,language = en),french = array (user_agent = Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; GTB6; .NET CLR 2.0.50727),language = fr,fr-FR;q=0.5);foreach ($urls as $url) echo URL: $urln;foreach ($browsers as $test_name = $browser) $ch = curl_i

9、nit();/ 设置 urlcurl_setopt($ch, CURLOPT_URL, $url);/ 设置浏览器的特定 headercurl_setopt($ch, CURLOPT_HTTPHEADER, array(User-Agent: $browseruser_agent, Accept-Language: $browserlanguage);/ 页面内容我们并不需要curl_setopt($ch, CURLOPT_NOBODY, 1);/只需返回HTTP headercurl_setopt($ch, CURLOPT_HEADER, 1);/ 返回结果,而不是输出它curl_setop

10、t($ch, CURLOPT_RETURNTRANSFER, 1);$output = curl_exec($ch);curl_close($ch);/有重定向的HTTP头信息吗?if (preg_match(!Location: (.*)!, $output, $matches) echo $test_name: redirects to $matches1n; else echo $test_name: no redirectionn;echo nn;首先,我们建立一组需要测试的URL,接着指定一组需要测试的浏览器信息。最后通过循 环测试各种 URL 和浏览器匹配可能产生的情况。因为我们指

11、定了 cURL选项,所以返回的输出内容则只包括HTTP头信息(被存放于$output 中)。利用一个简单的正则,我们检查这个头信息中是否包含了 “Location:”字样。运行这段代码应该会返回如下结果:URL: http : /www. cnn. corestandard: no ledirectionip-hone : redirects to http : /it. cnn. corefrench: no redirectionURL : http : /www.rtDzilla. corestandard: redirects to http : /www.rtozilla. coic

12、/en-US/ip-hone : redirects to http : /www.itcizilla. coic/en-US/french: redirects to http : /www.renzilla. coie/fr/URL: http : /www. facebook, corestandard: no ledirectioniphone : redirects to http : /tQacii. facebook. coie/ ?w2iefrencii: no redirection用POST方法发送数据当发起GET请求时,数据可以通过“查询字串”(query string)

13、传递给一个URL。例如,在 google中搜索时,搜索关键即为URL的查询字串的一部分: 这种情况下你可能并不需要cURL来模拟。把这个URL丢给“file_get_contents()”就能得到 相同结果。不过有一些HTML表单是用POST方法提交的。这种表单提交时,数据是通过HTTP请求 体(request body)发送,而不是查询字串。例如,当使用CodeIgniter论坛的表单,无论你 输入什么关键字,总是被POST到如下页面:你可以用PHP脚本来模拟这种URL请求。首先,新建一个可以接受并显示POST数据的文 件,我们给它命名为 post_output.php:print_r($_

14、POST);接下来,写一段PHP脚本来执行cURL请求:$url = http:/localhost/post_output.php;$post_data = array (foo = bar,query = Nettuts,action = Submit);$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);/ 我们在 POST 数据哦! curl_setopt($ch, CURLOPT_POST, 1);/ 把 post 的变量加上curl_se

15、topt($ch, CURLOPT_POSTFIELDS, $post_data); $output = curl_exec($ch);curl_close($ch);echo $output; 执行代码后应该会得到以下结果:Arrayfoo = tar qjery = Netfjts action = Suinuit这段脚本发送一个POST请求给post_output.php ,这个页面$_POST变量并返回,我们利 用 cURL 捕捉了这个输出。文件上传上传文件和前面的POST十分相似。因为所有的文件上传表单都是通过POST方法提交的。 首先新建一个接收文件的页面,命名为 upload_o

16、utput.php:print_r($_FILES);以下是真正执行文件上传任务的脚本:$url = http:/localhost/upload_output.php;$post_data = array (foo = bar,/ 要上传的本地文件地址upload = C:/wamp/www/test.zip);$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_POST, 1);curl_setop

17、t($ch, CURLOPT_POSTFIELDS, $post_data);$output = curl_exec($ch);curl_close($ch);echo $output;如果你需要上传一个文件,只需要把文件路径像一个 post 变量一样传过去,不过记得在前 面加上符号。执行这段脚本应该会得到如下输出:Array/jpload = Array;nane = test.zip;type = application/octet-streaiiitmp_name = C:wamptrapphpCC3.traperror = 0size = 1133642cURL 批处理(m ulti

18、cURL)cURL还有一个高级特性批处理句柄(handle)。这一特性允许你同时或异步地打开多个 URL 连接。下面是来自来自的示例代码:/ 创建两个 cURL 资源$ch1 = curl_init();$ch2 = curl_init();/指定URL和适当的参数curl_setopt($chl, CURLOPT_URL, curl_setopt($ch1, CURLOPT_HEADER, 0);curl_setopt($ch2, CURLOPT_URL, curl_setopt($ch2, CURLOPT_HEADER, 0);/ 创建 cURL 批处理句柄$mh = curl_multi

19、_init();/ 加上前面两个资源句柄curl_multi_add_handle($mh,$chl);curl_multi_add_handle($mh,$ch2);/ 预定义一个状态变量$active = null;/ 执行批处理do $mrc = curl_multi_exec($mh, $active); while ($mrc = CURLM_CALL_MULTI_PERFORM);while ($active & $mrc = CURLM_OK) if (curl_multi_select($mh) != -l) do $mrc = curl_multi_exec($mh, $ac

20、tive); while ($mrc = CURLM_CALL_MULTI_PERFORM);/ 关闭各个句柄curl_multi_remove_handle($mh, $chl);curl_multi_remove_handle($mh, $ch2);curl_multi_close($mh);这里要做的就是打开多个cURL句柄并指派给一个批处理句柄。然后你就只需在一个while 循环里等它执行完毕。这个示例中有两个主要循环。第一个 do-while 循环重复调用 curl_multi_exec() 。这个函数 是无隔断(non-blocking)的,但会尽可能少地执行。它返回一个状态值,只

21、要这个值等于 常量 CURLM_CALL_MULTI_PERFORM ,就代表还有一些刻不容缓的工作要做(例如, 把对应 URL 的 http 头信息发送出去)。也就是说,我们需要不断调用该函数,直到返回值 发生改变。而接下来的 while 循环,只在 $active 变量为 true 时继续。这一变量之前作为第二个参数 传给了 curl_multi_exec() ,代表只要批处理句柄中是否还有活动连接。接着,我们调用 curl_multi_select() ,在活动连接(例如接受服务器响应)出现之前,它都是被“屏蔽”的。 这个函数成功执行后,我们又会进入另一个 do-while 循环,继续下

22、一条 URL。 还是来看一看怎么把这一功能用到实处吧:WordPress 连接检查器 想象一下你有一个文章数目庞大的博客,这些文章中包含了大量外部网站链接。一段时间之 后,因为这样那样的原因,这些链接中相当数量都失效了。要么是被和谐了,要么是整个站 点都被功夫网了.我们下面建立一个脚本,分析所有这些链接,找出打不开或者 404 的网站/网页,并生成一 个报告。请注意,以下并不是一个真正可用的WordPress插件,仅仅是一段独立功能的脚本而已,仅 供演示,谢谢。好,开始吧。首先,从数据库中读取所有这些链接:/ CONFIG$db_host = localhost;$db_user = root

23、;$db_pass = ;$db_name = wordpress;$excluded_domains = array(localhost, );$max_connections = 10;/ 初始化一些变量$url_list = array();$working_urls = array();$dead_urls = array();$not_found_urls = array();$active = null;/ 连到 MySQLif (!mysql_connect($db_host, $db_user, $db_pass) die(Could not connect: . mysql_

24、error();if (!mysql_select_db($db_name) die(Could not select db: . mysql_error();/ 找出所有含有链接的文章$q = SELECT post_content FROM wp_postsWHERE post_content LIKE %href=%AND post_status = publishAND post_type = post;$r = mysql_query($q) or die(mysql_error();while ($d = mysql_fetch_assoc($r) / 用正则匹配链接if (pre

25、g_match_all(!href=(.*?)!, $dpost_content, $matches) foreach ($ches1 as $url) / exclude some domains $tmp = parse_url($url);if (in_array($tmphost, $excluded_domains) continue;/ store the url $url_list = $url;/ 移除重复链接$url_list = array_values(array_unique($url_list);if (!$url_list) die(No URL to check)

26、;我们首先配置好数据库,一系列要排除的域名($excluded_domains),以及最大并发连接数 ($max_connections)。然后,连接数据库,获取文章和包含的链接,把它们收集到一个数组 中( $url_list)。下面的代码有点复杂了,因此我将一小步一小步地详细解释:/ 1. 批处理器$mh = curl_multi_init();/ 2.加入需批量处理的URLfor ($i = 0; $i $max_connections; $i+) add_url_to_multi_handle($mh, $url_list);/ 3. 初始处理do $mrc = curl_multi_e

27、xec($mh, $active); while ($mrc = CURLM_CALL_MULTI_PERFORM);/ 4. 主循环while ($active & $mrc = CURLM_OK) / 5. 有活动连接if (curl_multi_select($mh) != -1) / 6. 干活do $mrc = curl_multi_exec($mh, $active); while ($mrc = CURLM_CALL_MULTI_PERFORM);/ 7. 有信息否?if ($mhinfo = curl_multi_info_read($mh) / 意味着该连接正常结束/ 8.从

28、curl句柄获取信息$chinfo = curl_getinfo($mhinfohandle);/ 9. 死链么?if (!$chinfohttp_code) $dead_urls = $chinfourl;/ 10. 404 了? else if ($chinfohttp_code = 404) $not_found_urls = $chinfourl;/ 11. 还能用 else $working_urls = $chinfourl;/ 12. 移除句柄 curl_multi_remove_handle($mh, $mhinfohandle); curl_close($mhinfohand

29、le);/ 13.加入新URL,干活if (add_url_to_multi_handle($mh, $url_list) do $mrc = curl_multi_exec($mh, $active); while ($mrc = CURLM_CALL_MULTI_PERFORM); / 14. 完了curl_multi_close($mh);echo =Dead URLs=n;echo implode(n,$dead_urls) . nn;echo =404 URLs=n;echo implode(n,$not_found_urls) . nn;echo =Working URLs=n;e

30、cho implode(n,$working_urls); 15.向批处理器添加urlfunction add_url_to_multi_handle($mh, $url_list) static $index = 0;/ 如果还剩 url 没用if ($url_list$index) / 新建 curl 句柄$ch = curl_init();/ 配置 urlcurl_setopt($ch, CURLOPT_URL, $url_list$index);/ 不想输出返回的内容curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);/ 重定向到哪儿我们就去哪儿cu

31、rl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);/ 不需要内容体,能够节约带宽和时间curl_setopt($ch, CURLOPT_NOBODY, 1);/ 加入到批处理器中curl_multi_add_handle($mh, $ch);/拨一下计数器,下次调用该函数就能添加下一个url 了$index+;return true; else / 没有新的 URL 需要处理了return false; 下面解释一下以上代码。列表的序号对应着代码注释中的顺序数字。新建一个批处理器。Created a multi handle.稍后我们将创建一个把 URL 加入

32、批处理器的函数 add_url_to_multi_handle() 。每当这个函 数被调用,就有一个新url被加入批处理器。一开始,我们给批处理器添加了 10个URL(这 一数字由 $max_connections 所决定)。运 行 curl_multi_exec() 进 行 初 始 化 工 作 是 必 须 的 , 只 要 它 返 回 CURLM_CALL_MULTI_PERFORM 就还有事情要做。这么做主要是为了创建连接,它不会 等待完整的URL响应。只要批处理中还有活动连接主循环就会一直持续。curl_multi_select()会一直等待,直到某个URL查询产生活动连接。cURL的活儿

33、又来了,主要是获取响应数据。检查各种信息。当一个URL请求完成时,会返回一个数组。在返回的数组中有一个cURL句柄。我们利用其获取单个cURL请求的相应信息。 如果这是一个死链或者请求超时,不会返回 http 状态码。如果这个页面找不到了,会返回 404状态码。 其他情况我们都认为这个链接是可用的(当然,你也可以再检查一下500错误之类.)。从该批次移除这个cURL句柄,因为它已经没有利用价值了,关了它!很好,现在可以另外加一个URL进来了。再一次地,初始化工作又开始进行. 嗯,该干的都干了。关闭批处理器,生成报告。回过头来看给批处理器添加新 URL 的函数。这个函数每调用一次,静态变量 $i

34、ndex 就递 增一次,这样我们才能知道还剩多少URL没处理。我把这个脚本在我的博客上跑了一遍(测试需要,有一些错误链接是故意加上的),结果如 下:共检查约40个URL,只耗费两秒不到。当需要检查更加大量的URL时,其省心省力的效 果可想而知!如果你同时打开10个连接,还能再快上10倍!另外,你还可以利用cURL批 处理的无隔断特性来处理大量URL请求,而不会阻塞你的Web脚本。另一些有用的 cURL 选项HTTP 认证如果某个URL请求需要基于HTTP的身份验证,你可以使用下面的代码: 复制内容到剪贴板代码:$url = $ch = curl_init();curl_setopt($ch,

35、CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);/ 发送用户名和密码curl_setopt($ch, CURLOPT_USERPWD, myusername:mypassword);/ 你可以允许其重定向curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);/ 下面的选项让 cURL 在重定向后/ 也能发送用户名和密码 curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 1);$output = curl_exec($ch); curl_close

36、($ch);FTP 上传PHP 自带有 FTP 类库, 但你也能用 cURL:/ 开一个文件指针$file = fopen(/path/to/file, r);/ url里包含了大部分所需信息$url = ftp:/username:password:21/path/to/new/file;$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);/ 上传相关的选项curl_setopt($ch, CURLOPT_UPLOAD, 1); curl_setop

37、t($ch, CURLOPT_INFILE, $fp);curl_setopt($ch, CURLOPT_INFILESIZE, filesize(/path/to/file);/ 是否开启 ASCII 模式 (上传文本文件时有用) curl_setopt($ch, CURLOPT_FTPASCII, 1);$output = curl_exec($ch);curl_close($ch);翻墙术你可以用代理发起cURL请求:$ch = curl_init();curl_setopt($ch, CURLOPT_URL,); curl_setopt($ch, CURLOPT_RETURNTRANS

38、FER, 1);/ 指定代理地址curl_setopt($ch, CURLOPT_PROXY, 11.11.11.11:8080);/ 如果需要的话,提供用户名和密码 curl_setopt($ch, CURLOPT_PROXYUSERPWD,user:pass);$output = curl_exec($ch);curl_close ($ch);回调函数可以在一个URL请求过程中,让cURL调用某指定的回调函数。例如,在内容或者响应下 载的过程中立刻开始利用数据,而不用等到完全下载完。$ch = curl_init();curl_setopt($ch, CURLOPT_URL,);curl_setopt($ch, CURLOPT_WRITEFUNCTION,progress_function); curl_exec($ch);curl_close ($ch);function progress_function($ch,$str) echo $str;return strlen($str); 这个回调函数必须返回字串的长度,不然此功能将无法正常使用。在URL响应接收的过程中,只要收到一个数据包,这个函数就会被调用。小结今天我们一起学习了 cURL库的强大功能和灵活的扩展性。希望你喜欢。下一次要发起URL 请求时,考虑下cURL吧!

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!