php多线程curl_multi_init的使用(代码片段)

rxbook rxbook     2022-11-30     361

关键词:

php中可以通过CURL处理HTTP请求,其中curl_init()是单线程模式,如果需要对事务处理走多线程模式,那么就需要用到curl_multi_init()函数。

本案例用来测试大并发的情况下 curl_multi_init() 到底比 curl_init() 快多少。

话不多少,直接上代码:

<?php
class Http

    /**
     * https 发起post请求
     * @param string $url url信息
     * @param mixed $data 参数信息[$data = ‘"a":1,"b":2‘ or $data = array("a" => 1,"b" => 2)]
     * @param int $timeOut 超时设置
     * @param string $proxyHost 代理host
     * @param int $proxyPort 代理端口
     * @return string
     */
    public static function post($url, $data = null, $timeOut = 20, $proxyHost = null, $proxyPort = null)
    
        try 
            if (strlen($url) < 1) 
                return null;
            

            $ch = curl_init();
            // 设置url
            curl_setopt($ch, CURLOPT_URL, $url);
            if (false == empty($data)) 
                curl_setopt($ch, CURLOPT_POST, 1);
                if (is_array($data) && count($data) > 0) 
                    curl_setopt($ch, CURLOPT_POST, count($data));
                
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

            // 如果成功只将结果返回,不自动输出返回的内容
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            // user-agent
            curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0");
            // 超时
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeOut);

            // 使用代理
            if (strlen($proxyHost) > 0 && strlen($proxyPort) > 0) 
                // 代理认证模式
                curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
                // 代理服务器地址
                curl_setopt($ch, CURLOPT_PROXY, $proxyHost);
                // 代理服务器端口
                curl_setopt($ch, CURLOPT_PROXYPORT, $proxyPort);
                // 使用http代理模式
                curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
            

            // 执行
            $out = curl_exec($ch);
            // 关闭
            curl_close($ch);
            return $out;
         catch (Exception $e) 
            return null;
        

    

    /**
     * https 发起post多发请求
     * @param array $nodes url和参数信息。
     * $nodes = [
     * [0] = > [
     * ‘url‘ => ‘http://www.baidu.com‘,
     * ‘data‘ => ‘"a":1,"b":2‘
     * ],
     * [1] = > [
     * ‘url‘ => ‘http://www.baidu.com‘,
     * ‘data‘ => null
     * ]
     * ....
     * ];
     * @param int $timeOut 超时设置
     * @return array
     */
    public static function postMulti($nodes, $timeOut = 5)
    
        try 
            if (false == is_array($nodes)) 
                return array();
            

            $mh = curl_multi_init();
            $curlArray = array();
            foreach ($nodes as $key => $info) 
                if (false == is_array($info)) 
                    continue;
                
                if (false == isset($info[url])) 
                    continue;
                

                $ch = curl_init();
                // 设置url
                $url = $info[url];
                curl_setopt($ch, CURLOPT_URL, $url);

                $data = isset($info[data]) ? $info[data] : null;
                if (false == empty($data)) 
                    curl_setopt($ch, CURLOPT_POST, 1);
                    // array
                    if (is_array($data) && count($data) > 0) 
                        curl_setopt($ch, CURLOPT_POST, count($data));
                    
                    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
                

                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
                // 如果成功只将结果返回,不自动输出返回的内容
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                // user-agent
                curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0");
                // 超时
                curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeOut);

                $curlArray[$key] = $ch;
                curl_multi_add_handle($mh, $curlArray[$key]);
            

            $running = NULL;
            do 
                usleep(10000);
                curl_multi_exec($mh, $running);
             while ($running > 0);

            $res = array();
            foreach ($nodes as $key => $info) 
                $res[$key] = curl_multi_getcontent($curlArray[$key]);
            
            foreach ($nodes as $key => $info) 
                curl_multi_remove_handle($mh, $curlArray[$key]);
            
            curl_multi_close($mh);
            return $res;
         catch (Exception $e) 
            return array();
        

    



$count = 10;

//2.1 循环调用Http::post() 100次
$url = https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=abcdasdfasdfasdfasdfasdfasdfasdfasdfasdf;
$startTime = microtime(true);
for ($i = 1; $i <= $count; $i++) 
    $res = Http::post($url);

$endTime = microtime(true);

echo $endTime - $startTime;
echo "\n";

//2.2 调用Http::postMulti()一次发100个url
$url = https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=abcdasdfasdfasdfasdfasdfasdfasdfasdfasdf;
$nodes = array();
for ($i = 1; $i <= $count; $i++) 
    $info = array();
    $info[url] = $url;
    $nodes[] = $info;


$startTime = microtime(true);
$res = Http::postMulti($nodes);
$endTime = microtime(true);

echo $endTime - $startTime;
echo "\n";

?>

运行结果:

* 当$count=10的情况下,耗时分别为:

3.4119510650635
0.44486904144287

curl_multi_init() 比 curl_init() 快了8倍。

* 当 $count=100的情况下,耗时分别为:

34.190015077591
1.9350771903992

curl_multi_init() 比 curl_init() 快了17倍。

 

php利用curl实现多进程下载文件类(代码片段)

...处理方法,开启多进程,实现批量下载文件。主要方法:curl_multi_init:返回一个新cURL批处理句柄curl_multi_add_handle:向curl批处 查看详情

如何在 PHP 应用程序中使用多线程

】如何在PHP应用程序中使用多线程【英文标题】:HowcanoneusemultithreadinginPHPapplications【发布时间】:2010-09-0909:49:28【问题描述】:是否有一种在PHP中实现多线程模型的现实方法,无论是真实的还是只是模拟它。前段时间有人建议... 查看详情

用php的curl实现并发请求远程文件(抓取远程网页)

 PHP的curl功能确实强大了。里面有个curl_multi_init功能,就是批量处理任务。可以利用此,实现多进程同步抓取多条记录,优化普通的网页抓取程序。一个简单的抓取函数:functionhttp_get_multi($urls){$count=count($urls);$data=[];$chs=[];//... 查看详情

phpcli是守护进程的吗

...注:windows和linux下都支持php_cli模式PHP-cli应用场景:1.多线程应用这方面的好处,引用鸟哥的话:优点:1.使用多进程,子进程结束以后,内核会负责回收资源2.使用多进程,子进程异常退出不会导致整个进程Thread退出.父进程还有机会... 查看详情

php实现多线程编程(代码片段)

来源:http://www.cnblogs.com/zhenbianshu/p/7978835.html多线程线程首先说下线程:线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个... 查看详情

我可以利用多线程 PHP 进行慢速 sql 查询吗

】我可以利用多线程PHP进行慢速sql查询吗【英文标题】:CanIleverageMulti-ThreadedPHPforslowsqlqueries【发布时间】:2021-06-1318:04:44【问题描述】:我的任务是链接两个不同API的id,链接将基于名称完成,因此使用通配符的搜索有点慢。例... 查看详情

jQuery POST 多线程延迟

】jQueryPOST多线程延迟【英文标题】:jQueryPOSTmultithreadeddelays【发布时间】:2017-10-0501:06:39【问题描述】:我正在使用PHP代码中的多线程POST请求。由于这些请求可能需要很长时间,我决定对这些POST请求进行多线程处理,以通过使... 查看详情

多线程中join方法的含义

...用:调用这个方法的时候,主进程会在这里停住,等待该线程进行完毕再继续往下执行。如:不使用join的情况:<?phpclassJoinextendsThread{publicfunctionrun(){sleep(3);echo__FUNCTION__.PHP_EOL;}}$join=newJoin();$join->start();echo‘justatest‘.PHP_EOL; 查看详情

多线程的使用

1为什么使用多线程  1.1发挥多核cpu的优势    单核CPU上的多线程是假的多线程,同一时间处理器只会处理一段逻辑,只是在多个线程之间进行快速切换    多核CPU才能实现真正的多线程,同时处理多个逻辑,充分利... 查看详情

python多进程和多线程的使用(代码片段)

...参数args和kwargs5.进程之间不共享全局变量6.守护进程7.多线程7.1线程介绍7.2多线程实现方式8.线程的无序执行9.守护线程10.线程之间共享全局变量11.线程共享全局变量出现的问题12.线程同步13.互斥锁14.解释一下互斥锁产生的死锁问... 查看详情

多线程开发+多线程使用共享数据-17

 进程:运行着的程序线程:每个进程里面至少包含一个线程,线程是操作系统创建的,用来控制代码执行的数据结构,线程就像代码的执行许可证单线程程序,主线程的入口就是代码的开头主线程顺序往下执行,直到所有的... 查看详情

多线程2-使用多线程(代码片段)

此章包含:  1、线程的实现方式、2、实例变量与线程安全3、线程常用的几个api4、停止线程5、暂停线程6、yield方法7、线程的优先级、8、守护线程。1、线程的常见实现方式有两种。继承Thread或实现Runable接口。代码如下://继... 查看详情

多线程和多进程的区别

...考技术A一般运行一个程序称为一个进程。进程可以创建线程,也可以创建进程。多线程和多进程的区别:线程是由进程管理的,线程之间、线程和父进程(创建线程的进程)之间可以共享内存变量(需要使用策略的)。进程之间一般... 查看详情

java多线程原理及thread类的使用

一、进程与线程的区别1.进程是应用程序在内存总分配的空间。(正在运行中的程序)2.线程是进程中负责程序执行的执行单元、执行路径。3.一个进程中至少有一个线程在负责进程的运行。4.一个进程中有多个线程在运行的程序... 查看详情

多线程线程同步

 一,线程的同步有以下方法  1,使用synchronized实现同步方法;  2,使用非依赖属性实现同步;  3,在同步代码块中使用条件;  4,使用锁实现同步;  5,使用读写同步数据访问;  6,修改锁的公平性;  ... 查看详情

java多线程的基本使用(代码片段)

文章目录1.多线程的概念2.线程的实现方式2.1继承Thread类实现多线程2.2实现Runnable接口实现多线程2.3实现Callable的多线程1.多线程的概念在程序执行的时候,即使没有开启多线程,Java后台也有多个线程在运行,最基本的... 查看详情

多线程介绍以及线程池的使用和业务场景

多线程介绍、列举线程池和业务场景:1).什么是多线程1个进程中可以开启多条线程,每条线程可以并行(同时)执行不同的任务进程->车间,线程->车间工人多线程技术可以提高程序的执行效率比如同时开启3条线程分别下... 查看详情

开发源码--php实现多线程

...时任务和自动任务有可能会发生并发,所以不得不考虑多线程。我在网上也找了很多资料貌似不符合我的需求,最后结合前辈的智慧和自己的专研,还是实现了; publicfunctiontesta(){        $id=$ 查看详情