1 Star 0 Fork 0

softtomorrow / CurlFuture

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

CurlFuture: PHP Curl并行轮转请求库

multicurl系列方法是提高php请求后端http接口的一种途径。但是直接使用的话,存在几方面问题:

  • 部分版本的curl扩展有bug,需要用特定的方式来调用(Rolling cURL: PHP并发最佳实践)
  • 网上流传的CurlRolling库都只支持前面加入,最后一并执行这种使用模式。而最理想的是随时加入,需要的时候从里面取出所需的结果,且不需等待其他请求返回
  • 为了提升效率,大部分库选择使用回调函数的方式来执行,对已有程序改造成本较高

为了解决这些问题,开发了CurlFuture库,实现了并行请求,先到先取,链式执行的特性。

应用场景

对于一些大型公司,PHP作为接口聚合层来使用,而接口通过HTTP协议给出。对于一些复杂的页面,可能需要请求几十个相互独立的接口, 如果使用并行模式,则可以极大的提升性能。

安装方法

引入入口php文件即可:include __DIR__.'/curl_future.php';

使用方法

/**
 * 获得一个延迟执行curl的类
 * @param $url 请求url地址
 * @param $options = array(), 
 *		header:头信息(Array), 
 *		proxy_url:代理服务器地址, 
 *		timeout:超时时间,可以小于1
 *		post_data: string|array post数据
 * @return CurlFuture\HttpFuture
 */
function curl_future($url, $options = array());

echo curl_future("http://s.newhua.com/2015/1113/304528.shtml?4", array())
		->fetch();

并行请求的实例(async.php)

include __DIR__.'/curl_future.php';

$f4 = curl_future("http://s.newhua.com/2015/1113/304528.shtml?4");
$f5 = curl_future("http://s.newhua.com/2015/1113/304528.shtml?5");

echo strlen($f1->fetch());	//这个地方会并行执行
echo "\n";
echo strlen($f2->fetch());
echo "\n";

链式执行的示例(then.php)

include __DIR__.'/curl_future.php';

echo curl_future("http://s.newhua.com/2015/1113/304528.shtml")
	->then(function($data){
		return strlen($data);
	})
	->then(function($len){
		return "Length: $len";
	})
	->fetch();

和Model/Service结合的示例(model.php)

include __DIR__.'/curl_future.php';

class BookModel{
	//接口串行调用的示例,通过then函数将处理过程串联起来
	static public function getTitleFuture($id){
		return curl_future("http://111.202.7.252/{$id}")
			->then(function($data){
				return strlen($data);
			})
			->then(function($data){
				$url = "http://111.202.7.252/{$data}";
				$html = curl_future($url)->fetch();
				preg_match('/title(.+?)\/title/is', $html, $matches);
				return $matches[1];
			});
	}
	
	//普通接口调用+后续处理的示例
	static public function getContentFuture($id){
		return curl_future("http://111.202.7.252/{$id}")
				->then(function($data){
					return substr($data, 0, 100);
				});
	}
}

//多个请求并行发出示例,这个地方用Model封装起来,便于和不同框架相结合
$t1 = BookModel::getTitleFuture('111');
$t2 = BookModel::getTitleFuture('222');
$t3 = BookModel::getTitleFuture('333');

$c1 = BookModel::getContentFuture('111');
$c2 = BookModel::getContentFuture('222');
$c3 = BookModel::getContentFuture('333');

//fetch函数会阻塞住,这个地方会把所有队列里面的请求发出,直到需要获取的t1的请求执行完再返回
var_dump($t1->fetch());
//由于上个fetch已经阻塞过了,下面的这个fetch很可能无需阻塞直接返回,也有可能上面的fetch没有执行完,此处阻塞住继续执行请求,直到拿到t2的数据
var_dump($t2->fetch());
var_dump($c3->fetch());

原理

在每次fetch的时候,开始事件循环。当所需http返回后,结束循环。继续执行php逻辑。

	//task_manager.php
	public function fetch($ch){
		$chKey = (int)$ch;

		//如果两个队列里面都没有,那么退出
		if(!array_key_exists($chKey, $this->runningTasks) && !array_key_exists($chKey, $this->finishedTasks) )return false;
	
		$active = 1;
		do{
			//如果任务完成了,那么退出
			if(array_key_exists($chKey, $this->finishedTasks))break;

			//执行multiLoop,直到该任务完成
			$active = $this->multiLoop();
			//如果执行出错,那么停止循环
			if($active === false)break;
		}while(1);
		
		return $this->finishTask($ch);
	}

性能测试

请求本机接口200次,nginx默认页面,同步、异步与file_get_contents对比

/example/bench.php

curl_future sync:384 ms
file_get_contents:390 ms
curl_futhre async:68 ms

curl_future sync:624 ms
file_get_contents:460 ms
curl_futhre async:69 ms

curl_future sync:463 ms
file_get_contents:355 ms
curl_futhre async:70 ms

curl_future sync:447 ms
file_get_contents:409 ms
curl_futhre async:66 ms

同步方式没有file_get_contents稳定,但是异步批量方式性能提升很明显。

参考项目

Copyright (c) 2015 zhangyue Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

CurlFuture 展开 收起
PHP
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
PHP
1
https://gitee.com/softtomorrow/CurlFuture.git
git@gitee.com:softtomorrow/CurlFuture.git
softtomorrow
CurlFuture
CurlFuture
master

搜索帮助