当前第2页 返回上一页
// CONFIG $db_host = 'localhost'; $db_user = 'root'; $db_pass = ''; $db_name = 'wordpress'; $excluded_domains = array( 'localhost', 'www.mydomain.com'); $max_connections = 10; // 初始化一些变量 $url_list = array(); $working_urls = array(); $dead_urls = array(); $not_found_urls = array(); $active = null; // 连到 MySQL if (!mysql_connect($db_host, $db_user, $db_pass)) { die('Could not connect: ' . mysql_error()); } if (!mysql_select_db($db_name)) { die('Could not select db: ' . mysql_error()); } // 找出所有含有链接的文章 $q = "SELECT post_content FROM wp_posts WHERE post_content LIKE '%href=%' AND post_status = 'publish' AND post_type = 'post'"; $r = mysql_query($q) or die(mysql_error()); while ($d = mysql_fetch_assoc($r)) { // 用正则匹配链接 if (preg_match_all("!href=\"(.*?)\"!", $d['post_content'], $matches)) { foreach ($matches[1] as $url) { // exclude some domains $tmp = parse_url($url); if (in_array($tmp['host'], $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'); } |
我们首先配置好数据库,一系列要排除的域名($excluded_domains),以及最大并发连接数($max_connections)。然后,连接数据库,获取文章和包含的链接,把它们收集到一个数组中($url_list)。
下面的代码有点复杂了,因此我将一小步一小步地详细解释:
// 1. 批处理器 $mh = curl_multi_init(); // 2. 加入需批量处理的URL for ($i = 0; $i < $max_connections; $i++) { add_url_to_multi_handle($mh, $url_list); } // 3. 初始处理 do { $mrc = curl_multi_exec($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. 从curl句柄获取信息 $chinfo = curl_getinfo($mhinfo['handle']); // 9. 死链么? if (!$chinfo['http_code']) { $dead_urls []= $chinfo['url']; // 10. 404了? } else if ($chinfo['http_code'] == 404) { $not_found_urls []= $chinfo['url']; // 11. 还能用 } else { $working_urls []= $chinfo['url']; } // 12. 移除句柄 curl_multi_remove_handle($mh, $mhinfo['handle']); curl_close($mhinfo['handle']); // 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) . "\n\n"; echo "==404 URLs==\n"; echo implode("\n",$not_found_urls) . "\n\n"; echo "==Working URLs==\n"; echo implode("\n",$working_urls); // 15. 向批处理器添加url function add_url_to_multi_handle($mh, $url_list) { static $index = 0; // 如果还剩url没用 if ($url_list[$index]) { // 新建curl句柄 $ch = curl_init(); // 配置url curl_setopt($ch, CURLOPT_URL, $url_list[$index]); // 不想输出返回的内容 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 重定向到哪儿我们就去哪儿 curl_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加入批处理器的函数 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没处理。
我把这个脚本在我的博客上跑了一遍(测试需要,有一些错误链接是故意加上的),结果如下:
<img border="0" src="/upload/201106/20110602225008534.png" /> |
共检查约40个URL,只耗费两秒不到。当需要检查更加大量的URL时,其省心省力的效果可想而知!如果你同时打开10个连接,还能再快上10倍!另外,你还可以利用cURL批处理的无隔断特性来处理大量URL请求,而不会阻塞你的Web脚本。
另一些有用的cURL 选项
HTTP 认证
如果某个URL请求需要基于 HTTP 的身份验证,你可以使用下面的代码:
复制内容到剪贴板代码:
$url = "http://www.somesite.com/members/"; $ch = curl_init(); curl_setopt($ch, 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($ch); |
FTP 上传
PHP 自带有 FTP 类库, 但你也能用 cURL:
// 开一个文件指针 $file = fopen("/path/to/file", "r"); // url里包含了大部分所需信息 $url = "ftp://username:password@mydomain.com: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_setopt($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,'http://www.example.com'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 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,'http://net.tutsplus.com'); 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吧!
原文:基于PHP的cURL快速入门
英文原文:http://net.tutsplus.com/tutorial%20...%20for-mastering-curl/
原文作者:Burak Guzel
标签:WordPress
返回前面的内容
相关阅读 >>
wordpress中利用ajax异步获取评论用户头像的方法
多个wordpress站点使用同一数据库的方法
wordpress高级自定义布局的内容编辑器(tinymce)模板
在wordpress中使用php脚本来判断访客来自什么国家
分享十五个最佳jquery 幻灯插件和教程
wordpress速度优化-nginx fastcgi_cache缓存加速
30 个很棒的php开源cms内容管理系统小结
php多用户博客系统分析[想做多用户博客的朋友,需要了解]
实现wordpress主题侧边栏切换功能的php脚本详解
在centos系统上从零开始搭建wordpress博客的全流程记录
更多相关阅读请进入《wordpress》频道 >>
转载请注明出处:木庄网络博客 » 基于PHP的cURL快速入门教程 (小偷采集程序)