CURL的学习和应用(附多线程实现)


Posted in PHP onJune 03, 2013

curl安装:

windows下面的安装
:修改php.ini文件的设置,找到php_curl.dll
//取消下在的注释extension=php_curl.dll
linux下面安装:

# wget http://curl.haxx.se/download/curl-7.17.1.tar.gz
# tar zxvf curl-7.17.1.tar.gz  //解压
#cd curl-7.17.1
# ./configure ?prefix=/usr/local/curl
# make
# make install

这是安装php之前安装的方法.
***************************phpinf查看是否加载成功!
使用curl的POST数据飞信接口
用curl 写了飞信接口吧,网上有很多,这里只是做个测试

$username = 13800138000;
$password = 123456;
$sendto = 13912345678;
$message = "测试一个试试看!";
$curlPost = 'username='.urlencode($username).'&password='.urlencode($password).'&sendto='.urlencode($sendto).'&message='.urlencode($message).'';
$ch = curl_init();//初始化curl
curl_setopt($ch,CURLOPT_URL,'http://sms.api.bz/fetion.php');//抓取指定网页
curl_setopt($ch, CURLOPT_HEADER, 0);//设置header
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_POST, 1);//post提交方式
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$data = curl_exec($ch);//运行curl
curl_close($ch);
print_r($data);//输出结果

返回的结果是:短信已提交到发送队列!
飞信接口的地址是http://sms.api.bz/
飞信接口模式:
http://sms.api.bz/fetion.php?username=您的移动飞信登录手机号
&password=您的移动飞信登录密码
&sendto=接收短信的飞信好友手机号
&message=短信内容
格式:http://sms.api.bz/fetion.php?username=13800138000&password=123456&sendto=13912345678&message=短信内容
注意要保持utf-8格式的,这点我犯错了

总结一下使用curl方法:

初始化curl

使用curl_setopt设置目标url,和其他选项,这些选项方法详细参考:http://cn2.php.net/manual/zh/ref.curl.php

curl_exec,执行curl

执行后,关闭curl
最后一步就是输出
一个最要的curl函数:curl_getinfo
curl_getinfo ( resource $ch [, int $opt = 0 ] )

<?php
/*curl实例
*/
$curl = curl_init();
// 设置你需要抓取的URL
curl_setopt($curl, CURLOPT_URL, 'http://www.baidu.com');
// 设置header
curl_setopt($curl, CURLOPT_HEADER, 0);
// 设置cURL 参数,要求结果保存到字符串中还是输出到屏幕上。
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
// 运行cURL,请求网页
$data = curl_exec($curl);
if($data === false){
 echo curl_error($curl);exit;
}
$info = curl_getinfo($curl);
// 关闭URL请求
curl_close($curl);
// 显示获得的数据
var_dump($info);
var_dump($data);

可以返回:

URLINFO_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实现多线程

curl一般用来抓取网页,第二种就是get或者post数据,第三种应用就是实现PHP的多线程任务
下面来实现多线程的

<?php
/*
curl 多线程抓取
*/
 /** 
     * curl 多线程 
     *  
     * @param array $array 并行网址 
     * @param int $timeout 超时时间
     * @return array 
     */ 
 function Curl_http($array,$timeout){
  $res = array();
  $mh = curl_multi_init();//创建多个curl语柄
 $startime = getmicrotime();
  foreach($array as $k=>$url){
   $conn[$k]=curl_init($url);        curl_setopt($conn[$k], CURLOPT_TIMEOUT, $timeout);//设置超时时间
        curl_setopt($conn[$k], CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
        curl_setopt($conn[$k], CURLOPT_MAXREDIRS, 7);//HTTp定向级别
        curl_setopt($conn[$k], CURLOPT_HEADER, 0);//这里不要header,加块效率
        curl_setopt($conn[$k], CURLOPT_FOLLOWLOCATION, 1); // 302 redirect
        curl_setopt($conn[$k],CURLOPT_RETURNTRANSFER,1);
        curl_multi_add_handle ($mh,$conn[$k]);
  }
  //防止死循环耗死cpu 这段是根据网上的写法
  do {
   $mrc = curl_multi_exec($mh,$active);//当无数据,active=true
  } while ($mrc == CURLM_CALL_MULTI_PERFORM);//当正在接受数据时
  while ($active and $mrc == CURLM_OK) {//当无数据时或请求暂停时,active=true
   if (curl_multi_select($mh) != -1) {
    do {
     $mrc = curl_multi_exec($mh, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
   }
  }
  foreach ($array as $k => $url) {
     curl_error($conn[$k]);
       $res[$k]=curl_multi_getcontent($conn[$k]);//获得返回信息
       $header[$k]=curl_getinfo($conn[$k]);//返回头信息
       curl_close($conn[$k]);//关闭语柄
       curl_multi_remove_handle($mh  , $conn[$k]);   //释放资源  
  }
  curl_multi_close($mh);
  $endtime = getmicrotime();
  $diff_time = $endtime - $startime;
  return array('diff_time'=>$diff_time,
      'return'=>$res,
     'header'=>$header  
     );
 }
 //计算当前时间
 function getmicrotime() {
     list($usec, $sec) = explode(" ",microtime());
     return ((float)$usec + (float)$sec);
 }
 //测试一下,curl 三个网址
 $array = array(
    "http://www.weibo.com/",
    "http://www.renren.com/",
    "http://www.qq.com/"
    );
 $data = Curl_http($array,'10');//调用
 var_dump($data);//输出
?>

关于do while的那段解释:

因为$active要等全部url数据接受完毕才变成false,所以这里用到了curl_multi_exec的返回值判断是否还有数据,
当有数 据的时候就不停调用curl_multi_exec,暂时没有数据就进入select阶段,新数据一来就可以被唤醒继续执行。
这里的好处就是CPU的无谓 消耗没有了。更详细的说明:http://hi.baidu.com/%D4%C2%D2%B9%C4%FD%ED%F8/blog/item/9dfcf4fbe6b84374024f563d.html
 

这个多线程的写法步骤:
第一步:调用curl_multi_init
第二步:循环调用curl_multi_add_handle
这一步需要注意的是,curl_multi_add_handle的第二个参数是由curl_init而来的子handle。
第三步:持续调用curl_multi_exec
第四步:根据需要循环调用curl_multi_getcontent获取结果
第五步:调用curl_multi_remove_handle,并为每个字handle调用curl_close
第六步:调用curl_multi_close
多线程的测试效果图:

CURL的学习和应用(附多线程实现)

总结:36个http请求,从执行的是时间顺序上来看,三个网站的ip交叉,说明是同时并发的!
—————————————————————————
linux命令下的curl
几种常见的使用方式:
下载作用:
直接下载 相当于wget
curl -o 1.jpg http://cgi2.tky.3web.ne.jp/~zzh/screen1.JPG
批量下载screen1.JPG?screen10.JPG
curl -O http://cgi2.tky.3web.ne.jp/~zzh/screen[1-10].JPG
断点下载
curl -c -O http://cgi2.tky.3wb.ne.jp/~zzh/screen1.JPG

反向代理功能
curl -x 123.45.67.89:1080 -o page.html http://www.yahoo.com
显示头文件
curl -I www.sina.com

PHP 相关文章推荐
PHP中一个控制字符串输出的函数
Oct 09 PHP
给php新手谈谈我的学习心得
Feb 25 PHP
codeigniter中测试通过的分页类示例
Apr 17 PHP
PHP中cookie和session的区别实例分析
Aug 28 PHP
php使用curl简单抓取远程url的方法
Mar 13 PHP
WordPress主题中添加文章列表页页码导航的PHP代码实例
Dec 22 PHP
如何使用php等比例缩放图片
Oct 12 PHP
Redis使用Eval多个键值自增的操作实例
Nov 04 PHP
php Session无效分析资料整理
Nov 29 PHP
浅谈PHP的$_SERVER[SERVER_NAME]
Feb 04 PHP
使用PHPExcel实现数据批量导出为excel表格的方法(必看)
Jun 09 PHP
php实现微信支付之退款功能
May 30 PHP
php魔术方法与魔术变量、内置方法与内置变量的深入分析
Jun 03 #PHP
PHP flush()与ob_flush()的区别详解
Jun 03 #PHP
PHP导出EXCEL快速开发指南--PHPEXCEL的使用详解
Jun 03 #PHP
PHP Cookie的使用教程详解
Jun 03 #PHP
PHP register_shutdown_function函数的深入解析
Jun 03 #PHP
深入PHP与浏览器缓存的分析
Jun 03 #PHP
PHP判断图片格式的七种方法小结
Jun 03 #PHP
You might like
让PHP更快的提供文件下载的代码
2012/06/13 PHP
php检测网页是否被百度收录的函数代码
2013/10/09 PHP
为PHP安装imagick时出现Cannot locate header file MagickWand.h错误的解决方法
2014/11/03 PHP
php5.2的curl-bug 服务器被php进程卡死问题排查
2016/09/19 PHP
php变量与JS变量实现不通过跳转直接交互的方法
2017/08/25 PHP
JavaScript库 开发规则
2009/01/31 Javascript
javascript Base类 包含基本的方法
2009/07/22 Javascript
网页中的图片的处理方法与代码
2009/11/26 Javascript
JavaScript 解析Json字符串的性能比较分析代码
2009/12/16 Javascript
jquery.post用法示例代码
2014/01/03 Javascript
我的NodeJs学习小结(一)
2014/07/06 NodeJs
下拉框select的绑定示例
2014/09/04 Javascript
javascript三元运算符用法实例
2015/04/16 Javascript
js 事件的传播机制(实例讲解)
2017/07/20 Javascript
vue+echarts实现动态绘制图表及异步加载数据的方法
2018/10/17 Javascript
微信小程序时间戳转日期的详解
2019/04/30 Javascript
简单使用webpack打包文件的实现
2019/10/29 Javascript
js函数和this用法实例分析
2020/03/13 Javascript
如何基于filter实现网站整体变灰功能
2020/04/17 Javascript
微信小程序点击滚动到指定位置的实现
2020/05/22 Javascript
vue-resource 拦截器interceptors使用详解
2021/01/18 Vue.js
Python文件与文件夹常见基本操作总结
2016/09/19 Python
PyQt5实现五子棋游戏(人机对弈)
2020/03/24 Python
Python调用C语言的实现
2019/07/26 Python
python 装饰器功能与用法案例详解
2020/03/06 Python
VScode连接远程服务器上的jupyter notebook的实现
2020/04/23 Python
德国PC硬件网站:CASEKING
2016/10/20 全球购物
Kivari官网:在线购买波西米亚服装
2018/10/29 全球购物
新员工培训个人的自我评价
2013/10/09 职场文书
《回乡偶书》教学反思
2014/04/12 职场文书
三年级学生评语
2014/04/23 职场文书
标准单位租车协议书
2014/09/23 职场文书
党员剖析材料范文
2014/09/30 职场文书
教师求职信怎么写
2015/03/20 职场文书
2016年学校招生广告语
2016/01/28 职场文书
Java实现聊天机器人完善版
2021/07/04 Java/Android