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 相关文章推荐
利用 window_onload 实现select默认选择
Oct 09 PHP
PHP 的几个配置文件函数
Dec 21 PHP
PHP表单验证的3个函数ISSET()、empty()、is_numeric()的使用方法
Aug 22 PHP
php自动注册登录验证机制实现代码
Dec 20 PHP
php去掉URL网址中带有PHPSESSID的配置方法
Jul 08 PHP
ThinkPHP结合AjaxFileUploader实现无刷新文件上传的方法
Oct 29 PHP
smarty自定义函数htmlcheckboxes用法实例
Jan 22 PHP
php实现的mongodb操作类
May 28 PHP
PHP实现多维数组转字符串和多维数组转一维数组的方法
Aug 08 PHP
php三种实现多线程类似的方法
Oct 30 PHP
PHP读取zip文件的方法示例
Nov 17 PHP
Windows服务器中PHP如何安装redis扩展
Sep 27 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 强制下载文件代码
2010/10/24 PHP
php操作MongoDB基础教程(连接、新增、修改、删除、查询)
2014/03/25 PHP
php利用curl抓取新浪微博内容示例
2014/04/27 PHP
PHP过滤黑名单关键字的方法
2014/12/01 PHP
PHP闭包函数详解
2016/02/13 PHP
laravel利用中间件防止未登录用户直接访问后台的方法
2019/09/30 PHP
Add Formatted Data to a Spreadsheet
2007/06/12 Javascript
在JQuery dialog里的服务器控件 事件失效问题
2010/12/08 Javascript
javascript 基础篇1 什么是js 建立第一个js程序
2012/03/14 Javascript
ExtJS4 动态生成的grid导出为excel示例
2014/05/02 Javascript
jQuery遍历json中多个map的方法
2015/02/12 Javascript
常用DOM整理
2015/06/16 Javascript
js实现简洁的滑动门菜单(选项卡)效果代码
2015/09/04 Javascript
jQuery获取选中单选按钮radio的值
2016/12/27 Javascript
inner join 内联与left join 左联的实例代码
2017/09/18 Javascript
Vue filter介绍及其使用详解
2017/10/21 Javascript
使用Bootstrap4 + Vue2实现分页查询的示例代码
2017/12/21 Javascript
[57:55]EG vs Fnatic 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
Python中用psycopg2模块操作PostgreSQL方法
2017/11/28 Python
Django admin实现图书管理系统菜鸟级教程完整实例
2017/12/12 Python
利用Python将文本中的中英文分离方法
2018/10/31 Python
详解Python可视化神器Yellowbrick使用
2019/11/11 Python
使用Python爬虫库requests发送请求、传递URL参数、定制headers
2020/01/25 Python
python raise的基本使用
2020/09/10 Python
基于MUI框架使用HTML5实现的二维码扫描功能
2018/03/01 HTML / CSS
培训演讲稿范文
2014/01/12 职场文书
创先争优活动承诺书
2014/08/30 职场文书
2014年结对帮扶工作总结
2014/12/17 职场文书
工作检讨书范文
2015/01/23 职场文书
2015年法制宣传月活动总结
2015/03/26 职场文书
广告公司文案策划岗位职责
2015/04/14 职场文书
海洋天堂观后感
2015/06/05 职场文书
红灯733-1型14管5波段半导体收音机
2021/04/22 无线电
redis实现排行榜功能
2021/05/24 Redis
Windows安装Anaconda3的方法及使用过程详解
2021/06/11 Python
基于Python实现nc批量转tif格式
2022/08/14 Python