PHP开发——异步请求

由来

php一直以同步流程而著名(抛开swoole,wokerman不谈),写php代码只需要想清楚流程,基本不需要操心多线程的问题,而这也是我独爱PHP的原因。直到解除到了yield这个关键字。

yeild

生成器函数看上去就像一个普通函数, 除了不是返回一个值之外, 生成器会根据需求产生更多的值。

其实一开始,并没有觉得它是一个很了不起的关键字。直到看了在《PHP中使用协程实现多任务调度》中详细介绍了如何使用yield来实现任务调度。说实话,我并没有看懂。因为他的思维实在是很绕很绕,在没有静下心来的情况下,真的很难很难理解他的思路。

但不影响我开始关注yeild这个函数。并且开始寻找yeild使用的实际示例。

直到刷到guzzle/http/client的相关示例后,才知道,原来php也是可以支持异步请求的。

#文件request.php
<?php
require_once 'vendor/autoload.php';
use GuzzleHttp\Promise;


$request = new \app\common\util\RequestUtil();
$promises[] = $request->setUrl('http://127.0.0.1/test.php?time=2&id=1')->setData([])->setHeaders([])->setMethod('GET')->request()
  ->then(fn(\GuzzleHttp\Psr7\Response $res) => var_dump($res->getBody()->getContents()));

$promises[] = $request->setUrl('http://127.0.0.1/test.php?time=1&id=2')->setMethod('GET')->request()
  ->then(fn(\GuzzleHttp\Psr7\Response $res) => var_dump($res->getBody()->getContents()));

Promise\Utils::settle($promises)->wait();

#文件public/test.php
<?php
sleep($_GET['time'] ?? 5);
echo json_encode(['code' => $_GET['id']]);

# php ./request.php
\test.php:11:
string(12) "{"code":"2"}"
\test.php:9:
string(12) "{"code":"1"}"

我们用request.php请求public/test.php。

可以发现优先输出的是ID为2的数据。