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+SQLite存储方案
Sep 04 PHP
ThinkPHP调用百度翻译类实现在线翻译
Jun 26 PHP
PHP生成数组再传给js的方法
Aug 07 PHP
PHP动态柱状图实现方法
Mar 30 PHP
PHP里的单例类写法实例
Jun 25 PHP
php实现的简易扫雷游戏实例
Jul 09 PHP
深入浅析php json 格式控制
Dec 24 PHP
php使用ftp实现文件上传与下载功能
Jul 21 PHP
PHP如何实现订单的延时处理详解
Dec 30 PHP
laravel5.1 ajax post 传值_token示例
Oct 24 PHP
PHP设计模式之数据访问对象模式(DAO)原理与用法实例分析
Dec 12 PHP
tp5.0框架隐藏index.php入口文件及模块和控制器的方法分析
Feb 11 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
3
2006/10/09 PHP
处理php自动反斜杠的函数代码
2010/01/05 PHP
yii2学习教程之5种内置行为类详解
2017/08/03 PHP
js中的window.open返回object的错误的解决方法
2009/08/15 Javascript
ExtJS的FieldSet的column列布局
2009/11/20 Javascript
基于jquery的用鼠标画出可移动的div
2012/09/06 Javascript
js单向链表的具体实现实例
2013/06/21 Javascript
Nodejs异步回调的优雅处理方法
2014/09/25 NodeJs
JS模拟并美化的表单控件完整实例
2015/08/19 Javascript
AngularJS基础 ng-cloak 指令简单示例
2016/08/01 Javascript
javascript删除html标签函数cIsHTML
2017/01/09 Javascript
使用vue.js编写蓝色拼图小游戏
2017/03/17 Javascript
Angularjs根据json文件动态生成路由状态的实现方法
2017/04/17 Javascript
js 客户端打印html 并且去掉页眉、页脚的实例
2017/11/03 Javascript
vue项目优化之通过keep-alive数据缓存的方法
2017/12/11 Javascript
深入理解requireJS-实现一个简单的模块加载器
2018/01/15 Javascript
React之PureComponent的使用作用
2018/07/10 Javascript
vue框架搭建之axios使用教程
2018/07/11 Javascript
深入解析微信小程序开发中遇到的几个小问题
2020/07/11 Javascript
vue-quill-editor 自定义工具栏和自定义图片上传路径操作
2020/08/03 Javascript
Ajax获取node服务器数据的完整步骤
2020/09/20 Javascript
如何在Express4.x中愉快地使用async的方法
2020/11/18 Javascript
[01:51]2018年度CS GO最具人气外援-完美盛典
2018/12/16 DOTA
linux系统使用python获取cpu信息脚本分享
2014/01/15 Python
Python处理中文标点符号大集合
2018/05/14 Python
使用Python将Mysql的查询数据导出到文件的方法
2019/02/25 Python
浅谈如何使用python抓取网页中的动态数据实现
2020/08/17 Python
python实现感知机模型的示例
2020/09/30 Python
实例讲解HTML5的meta标签的一些应用
2015/12/08 HTML / CSS
Weblogc domain问题
2014/01/27 面试题
QA工程师岗位职责
2013/11/20 职场文书
十八届三中全会学习方案
2014/02/16 职场文书
2014两会优秀的心得体会范文
2014/03/17 职场文书
物业管理专业自荐信
2014/07/01 职场文书
师范生见习自我总结
2015/06/23 职场文书
使用 Apache Dubbo 实现远程通信(微服务架构)
2022/02/12 Servers