php中foreach curl实现多线程例子

 更新时间:2016年11月25日 17:18  点击:1945
多线程是php不支持的但我们可以通过foreach来伪多线程了,但这个伪多线程速度不一定比单线程要单到哪里去了,具体来看个例子。

在利用foreach语句循环图片URL,并通过CURL将所有图片进行本地保存的函数时 ,出现了只能采集到一个的问题。现将foreach和CURL结合进行多URL请求的方法进行下总如。

方法1:循环请求

$sr=array(url_1,url_2,url_3);
foreach ($sr as $k=>$v) {
    $curlPost=$v.'?f=传入参数';
    $ch = curl_init($curlPost) ;
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, true) ; // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回
    $data = curl_exec($ch) ;
    echo $k.'##:'.$data.'<br>';
}
curl_close($ch); 

上面代码需要特别注意的是,curl_close 一定要放在foreach循环结束的外面,如果放在里面的话,就会出现我上面提到的多个IMGURL ,只能采集到一个URL的问题。

方法2:多线程循环

<?php
multi_threads_request($nodes){
        $mh = curl_multi_init();
        $curl_array = array();
        foreach($nodes as $i => $url)
        {
            $curl_array[$i] = curl_init($url);
            curl_setopt($curl_array[$i], CURLOPT_RETURNTRANSFER, true);
            curl_multi_add_handle($mh, $curl_array[$i]);
        }
        $running = NULL;
        do {
            usleep(10000);
            curl_multi_exec($mh,$running);
        } while($running > 0);
        $res = array();
        foreach($nodes as $i => $url)
        {
            $res[$url] = curl_multi_getcontent($curl_array[$i]);
        }
        foreach($nodes as $i => $url){
            curl_multi_remove_handle($mh, $curl_array[$i]);
        }
        curl_multi_close($mh);
        return $res;
}
print_r(multi_threads_request(array(
    'http://www.111cn.net',
    'http://qq.111cn.net',
)); 

这里主要利用curl_multi_init()实现多个url 的请求,不过由于php自身并不支持多线程。所以伪多线程速度也不见得会比单线程快。

xml转成json与json转成xml都是非常的简单了,但小编在网上找了N久没有找到,下面给各位整理一篇php xml与json间的相互转换例子,有兴趣的可进入看看。

今天在网上想找个将xml转成json的方法,找了半天没找到,找到了,根本没有什么用,有一个service_JSON说的挺像真的,找开后就一个JSON.php,php5.0以后已经把它加进来,json_decode和json_encode。想走捷径的,唉,靠人不如靠已。以下是我写的一个方法

一,参考xml文件如下
 

 代码如下 复制代码
<?xml version="1.0" encoding="UTF-8"?> 
  <humans> 
  <zhangying> 
  <name>张映</name> 
  <sex>男</sex> 
  <old>28</old> 
  </zhangying> 
  <tank> 
  <name>tank</name> 
  <sex> 
 <hao>yes</hao> 
 <aaaa>no</aaaa> 
 </sex> 
  <old>28</old> 
  </tank> 
  </humans> 

二,xml转换成json

利用simplexml
 

 代码如下 复制代码

public function xml_to_json($source) { 
    if(is_file($source)){             //传的是文件,还是xml的string的判断 
        $xml_array=simplexml_load_file($source); 
    }else{ 
        $xml_array=simplexml_load_string($source); 
    } 
    $json = json_encode($xml_array);  //php5,以及以上,如果是更早版本,?下?JSON.php 
    return $json; 

三,json

转换成xml

利用递归函数

 代码如下 复制代码
 
public function json_to_xml($source,$charset='utf8') { 
    if(emptyempty($source)){ 
        return false; 
    } 
    $array = json_decode($source);  //php5,以及以上,如果是更早版本,?下?JSON.php 
    $xml  ='<!--l version="1.0" encoding="'.$charset.'-->'; 
    $xml .= $this->change($array); 
    return $xml; 

 
public function change($source) { 
    $string="";
    foreach($source as $k=>$v){
        $string .="<".$k.">";
        if(is_array($v) || is_object($v)){       //判断是否是数组,或者,对像
            $string .= $this->change($v);        //是数组或者对像就的递归调用
        }else{
            $string .=$v;                        //取得标签数据
        }
        $string .=""; 
    } 
    return $string; 

上面的方法json_to_xml,可以支持<name>aaaa</name>,不支持<name type='test'>aaaaa</name>看代码就能看明白。

多重筛选其实对于php程序员开发者来讲是非常的简单了,下面来介绍在PHPCMS实现多重筛选实现例子,有需要了解的朋友一起来看看吧.

在我们使用PHPCMS开发一些产品展示类网站的时候,由于分类的多样化,我们需要客户在简短的时间内寻找到自己需要的产品,这样我们就会用到分类的多重筛选,也就是类似京东,淘宝等这么电商网站里面的产品筛选的功能,PHPCMS本身并没有这样的功能,需要我们进行二次开发,当然网上也出现了很多这样的功能,但不知道为什么,按照上面的步骤能实现的时候并不多,在经过一系列的查找和自己测试之后,我自己总结了以下的方法,希望后来者看到之后可以省去很多不必要的麻烦,我会尽可能的详细写出是怎么实现的。 实现的效果在这里就不贴图片了,淘宝,京东上比我做的还好。

首先,要实现这个功能,在建立字段的时候字段的类型必须选择box类型,在是否作为筛选字段的项目里勾选“是”,是否作为搜索条件勾选“是”。

这建立好字段之后,剩下的就是怎么实现这个功能了。咱们需要在PHPCMS的自定义函数库这个文件里编写相应的分类筛选函数,代码如下:

/**
 * 通过指定keyid形式显示所有联动菜单
 * @param  $keyid 菜单主id
 * @param  $linkageid  联动菜单id,0调用顶级
 * @param  $modelid 模型id
 * @param  $fieldname  字段名称
 */
function show_linkage($keyid, $linkageid = 0, $modelid = '', $fieldname='zone') {
    $datas = $infos = $array = array();
    $keyid = intval($keyid);
    $linkageid = intval($linkageid);
    //当前菜单id
    $field_value = intval($_GET[$fieldname]);
    $urlrule = structure_filters_url($fieldname,$array,1,$modelid);
    if($keyid == 0) return false;
    $datas = getcache($keyid,'linkage');
    $infos = $datas['data'];

    foreach($infos as $k=>$v){
        if($v['parentid']==$field_value){
            $array[$k]['name'] = $v['name'];
            $array[$k]['value'] = $k;
            $array[$k]['url'] = str_replace('{$'.$fieldname.'}',$k,$urlrule);
            $array[$k]['menu'] = $field_value == $k ? '<a class="click" style="color:#fff;">'.$v['name'].'</a>' : '<a href='.$array[$k]['url'].'>'.$v['name'].'</a>' ;
        }
    }
    return $array;
}
 function structure_filters_url($fieldname,$array=array(),$type = 1,$modelid) {
    if(empty($array)) {
        $array = $_GET;
    } else {
        $array = array_merge($_GET,$array);
    }
    //TODO
    $fields = getcache('model_field_'.$modelid,'model');
    if(is_array($fields) && !empty($fields)) {
        ksort($fields);
        foreach ($fields as $_v=>$_k) {
            if($_k['filtertype'] || $_k['rangetype']) {
                if(strpos(URLRULE,'.html') === FALSE) $urlpars .= '&'.$_v.'={$'.$_v.'}';
                else $urlpars .= '-{$'.$_v.'}';
            }
        }
    }
    //后期增加伪静态等其他url规则管理,apache伪静态支持9个参数
    if(strpos(URLRULE,'.html') === FALSE) $urlrule =APP_PATH.'index.php?m=content&c=index&a=lists&catid={$catid}'.$urlpars.'&page={$page}' ;
    else $urlrule =APP_PATH.'list-{$catid}'.$urlpars.'-{$page}.html#wrap';
    //根据get传值构造URL
    if (is_array($array)) foreach ($array as $_k=>$_v) {
        if($_k=='page') $_v=1;
        if($type == 1) if($_k==$fieldname) continue;
        $_findme[] = '/{\$'.$_k.'}/';
        $_replaceme[] = $_v;
    }
     //type 模式的时候,构造排除该字段名称的正则
    if($type==1) $filter = '(?!'.$fieldname.'.)';
    $_findme[] = '/{\$'.$filter.'([a-z0-9_]+)}/';
    $_replaceme[] = '0';       
    $urlrule = preg_replace($_findme, $_replaceme, $urlrule);  
    return  $urlrule;
}
/**
 * 生成分类信息中的筛选菜单
 * @param $field   字段名称
 * @param $modelid  模型ID
 */
function filters($field,$modelid,$diyarr = array()) {
    $fields = getcache('model_field_'.$modelid,'model');
    $options = empty($diyarr) ?  explode("\n",$fields[$field]['options']) : $diyarr;
    $field_value = intval($_GET[$field]);
    foreach($options as $_k) {
        $v = explode("|",$_k);
        $k = trim($v[1]);
        $option[$k]['name'] = $v[0];
        $option[$k]['value'] = $k;
        $option[$k]['url'] = structure_filters_url($field,array($field=>$k),2,$modelid);
        $option[$k]['menu'] = $field_value == $k ? '<a class="click" style="color:#fff;">'.$v[0].'</a>' : '<a href='.$option[$k]['url'].'>'.$v[0].'</a>' ; //这个地方的a标签的class可以改成符合你自己网站的样式,
    }
    $all['name'] = '全部';//'全部';
    $all['url'] = structure_filters_url($field,array($field=>'0'),2,$modelid);
    $all['menu'] = $field_value == '' ? '<a class="click" style="color:#fff;">'.$all['name'].'</a>' : '<a href='.$all['url'].'>'.$all['name'].'</a>';

    array_push($option,$all);  
    return $option;
}


把上面的这段代码复制到:extention.func.php这个文件里,在前台调用的时候需要一点点的改动,调用代码如下:

{php $sql = structure_filters_sql($modelid);}
{pc:content action="lists" where="$sql" catid="$catid" modelid="$modelid" num="12" page="$page"}


再调用的时候一定不要忽略了catid和modelid,二者缺其一无法调用。产品分类怎么调用呢?相信大家也看到了,在刚刚添加的函数里面有一个fliters函数,我们使用这个函数来调用已添加的box类型的字段,读取出我们需要进行筛选的分类。代码如下:


{loop filters('fengge',$modelid) $r} //filters('需要调用的字段','字段所在的模型ID')
<li>{$r[menu]}</li>
{/loop}


好了,在进行了如上几个步骤之后,你就会发现前台的分类筛选功能已经可以使用了,这时你是否是发现URL太长太不美观?没关系,假如你的空间支持伪静态的话,就可以把网站的URL调的简单美观。PHPCMS安装包里自带了一个.htaccess文件,直接复制到根目录里就好了。如果是IIS服务器的话,需要httpd.ini文件,转化一下就可以了,现在的IIS7有一个导入规则的功能,可以直接把.htaccess文件转化成web.config文件,这样就实现了伪静态。一定要注意,把你自己添加的box筛选字段也加入到伪静态的规则里,否则是出现一些不必要的错误。

XHProf是一个分层PHP性能分析工具。它报告函数级别的请求次数和各种指标,包括阻塞时间,CPU时间和内存使用情况。现在我们来聊聊XHProf在开发环境中如何测试php性能。

以百分之一的概率产生测试数据,尽量不影响正式环境效率。

class XHProf {

    // private $XHProfPath = ‘xhprof/’;
    private $XHProfPath = ‘/usr/local/apache/htdocs/xhprof/’;
    private $applicationName = ‘sias_application’;
    private $sampleSize = 100;
    private static $enabled = false;

    public function XHProf_Start() {
        if (mt_rand(1, $this->sampleSize) == 1) {
            include_once $this->XHProfPath . ‘xhprof_lib/utils/xhprof_lib.php’;
            include_once $this->XHProfPath . ‘xhprof_lib/utils/xhprof_runs.php’;
            xhprof_enable(XHPROF_FLAGS_NO_BUILTINS + XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);

            self::$enabled = true;
        }
    }

    public function XHProf_End() {
        if (self::$enabled) {
            $XHProfData = xhprof_disable();

            $XHProfRuns = new XHProfRuns_Default();
            $XHProfRuns->save_run($XHProfData, $this->applicationName);
        }
    }

}


测试效果:

Overall Summary    
Total Incl. Wall Time (microsec):     48,162 microsecs
Total Incl. CPU (microsecs):     32,994 microsecs
Total Incl. MemUse (bytes):     2,773,464 bytes
Total Incl. PeakMemUse (bytes):     2,867,664 bytes
Number of Function Calls:     749

使用xhprof在开发环境中测试php性能

使用xhprof在开发环境中测试php性能

从以下测试结果看出,耗时最多的居然是连接数据库,所以我们来尽量优化数据库。

php CURL函数可以模仿用户进行一些操作,如我们可以模仿用户提交数据也可以模仿用户进行网站访问了,下面我们来介绍利用CURL模拟进行微信接口的GET与POST例子,例子非常的简单就两个大家一起看看.

Get提交获取数据

 /**
  * @desc 获取access_token
  * @return String access_token
  */ 
 function getAccessToken(){ 
     $AppId = '1232assad13213123'; 
     $AppSecret = '2312312321adss3123213'; 
     $getUrl = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$AppId.'&secret='.$AppSecret; 
     $ch = curl_init(); 
     curl_setopt($ch, CURLOPT_URL, $getUrl); 
     curl_setopt($ch, CURLOPT_HEADER, 0); 
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
     curl_setopt($ch, CURL_SSLVERSION_SSL, 2); 
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
     curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 
     $data = curl_exec($ch); 
     $response = json_decode($data); 
     return $response->access_token; 
 } 

Post提交获取数据

  /**
   * @desc 实现天气内容回复
   */ 
public function testWeixin(){ 
$access_token = $this->getAccessToken(); 
$customMessageSendUrl = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token='.$access_token; 
$description = '今天天气的详细信息(从第三方获取)。'; 
$url = 'http://weather.com/'; 
$picurl = 'http://weather.com/'; 
$postDataArr = array( 
'touser'=>'OPENID', 
'msgtype'=>'news', 
'news'=>array( 
    'articles'=>array( 
  'title'=>'当天天气', 
  'description'=>$description, 
  'url'=>$url, 
  'picurl'=>$picurl, 
    ), 
), 
); 
$postJosnData = json_encode($postDataArr); 
$ch = curl_init($customMessageSendUrl);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postJosnData);   
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 
$data = curl_exec($ch);
var_dump($data); 

例子相对来说比较简单也没有什么好详细分析的了,大家照抄就可以实现我们想要的功能了.

[!--infotagslink--]

相关文章

  • C# WinForm多线程解决界面卡死问题的完美解决方案,使用BeginInvoke

    问题描述:当我们的界面需要在程序运行中不断更新数据时,当一个textbox的数据需要变化时,为了让程序执行中不出现界面卡死的现像,最好的方法就是多线程来解决一个主线程来创建界...2020-06-24
  • Linux下PHP安装curl扩展支持https例子

    安装curl扩展支持https是非常的重要现在许多的网站都使用了https了,下面我们来看一篇关于PHP安装curl扩展支持https例子吧。 问题: 线上运行的lamp服务器,默认yu...2016-11-25
  • c# 多线程处理多个数据的方法

    这篇文章主要介绍了c# 多线程处理多个数据的方法,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下...2021-03-31
  • php中的foreach函数的2种用法

    Foreach 函数(PHP4/PHP5)foreach 语法结构提供了遍历数组的简单方式。foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。...2013-09-28
  • 浅谈Java8 的foreach跳出循环break/return

    这篇文章主要介绍了Java8 的foreach跳出循环break/return,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-28
  • C#基于委托实现多线程之间操作的方法

    这篇文章主要介绍了C#基于委托实现多线程之间操作的方法,实例分析了C#的委托机制与多线程交互操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • C#多线程中的异常处理操作示例

    这篇文章主要介绍了C#多线程中的异常处理操作,涉及C#多线程及异常的捕获、处理等相关操作技巧,需要的朋友可以参考下...2020-06-25
  • 深入分析C#中的异步和多线程

    这篇文章主要介绍了C#中异步和多线程的相关资料,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下...2021-01-16
  • C#多线程与异步的区别详解

    多线程和异步操作两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性。甚至有些时候我们就认为多线程和异步操作是等同的概念。但是,多线程和异步操作还是有一些区别的。而这些区别造成了使用多线程和异步操作的时机的区别...2020-06-25
  • C#多线程之Thread类详解

    这篇文章主要为大家详细介绍了C#多线程之Thread类,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • java中多线程与线程池的基本使用方法

    在Java中,我们可以利用多线程来最大化地压榨CPU多核计算的能力,下面这篇文章主要给大家介绍了关于java中多线程与线程池基本使用的相关资料,需要的朋友可以参考下...2021-09-13
  • php使用floor去掉小数点的例子

    floor会产生小数了如果我们不希望有小数我们是可以去除小数点的了,下面一聚教程小编来为各位介绍php使用floor去掉小数点的例子,希望对各位有帮助。 float floor (...2016-11-25
  • mybatis-plus  mapper中foreach循环操作代码详解(新增或修改)

    这篇文章主要介绍了mybatis-plus mapper中foreach循环操作代码详解(新增或修改),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-11-17
  • C#中的多线程多参数传递详解

    第一种解决方案的原理是:将线程执行的方法和参数都封装到一个类里面。通过实例化该类,方法就可以调用属性来实现间接的类型安全地传递多个参数...2020-06-25
  • JavaScript中的数组遍历forEach()与map()方法以及兼容写法介绍

    下面小编就为大家带来一篇JavaScript中的数组遍历forEach()与map()方法以及兼容写法介绍。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2016-05-20
  • java多线程中执行多个程序的实例分析

    在本篇文章里小编给大家整理的是一篇关于java多线程中执行多个程序的实例分析内容,有需要的朋友们可以学习参考下。...2021-02-07
  • 解析C#多线程编程中异步多线程的实现及线程池的使用

    这篇文章主要介绍了C#多线程编程中异步多线程的实现及线程池的使用,同时对多线程的一般概念及C#中的线程同步并发编程作了讲解,需要的朋友可以参考下...2020-06-25
  • Springboot实现多线程注入bean的工具类操作

    这篇文章主要介绍了Springboot实现多线程注入bean的工具类操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-27
  • c# winform 关闭窗体时同时结束线程实现思路

    th.IsBackground = true解决线程问题,意思就是把线程设置为后台线程,感兴趣的朋友可以多了解下,如何有什么妙招还请多多指导哈...2020-06-25
  • Nodejs 数组的队列以及forEach的应用详解

    这篇文章主要介绍了Nodejs 数组的队列以及forEach的应用详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-25